c++ - 为什么 boost 的 managed_mapped_file::shrink_to_fit 在 Windows 和 Linux 上表现不同?

标签 c++ linux boost

这是关于 C++ 库的 boost 。

managed_mapped_file::shrink_to_fit 函数在 Linux 和 Windows 上的工作方式不同。

在 Linux 上,即使目标实例存在,此函数也会成功。 但是,在 Windows 上,如果目标实例存在,此函数将失败。

这是正确的行为吗?

做同样的行为似乎是正确的,这是一个错误吗?

我把示例代码放在下面。

编译环境

  • boost:version.1.65.1

  • window

    • VisualStudio2017
    • WSL(Ubuntu16.04)
  • Linux

    • UbuntuServer17.10,
    • Clang++5.0,
    • g++7.2.0

编译

clang++-5.0 -std=c++1z ./test.cpp -o test -lpthread

#define BOOST_DATE_TIME_NO_LIB
#include <boost/interprocess/managed_mapped_file.hpp>
#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <vector>
#include <iostream>
namespace bip = boost::interprocess;
using intAlloc = bip::allocator<int, bip::managed_mapped_file::segment_manager>;
using intVec = std::vector<int, intAlloc>;

int main() {
    bip::managed_mapped_file *p_file_vec;
    intVec *vecObj;

    std::string fileName = "tmp.dat";
    size_t fileSize = 1024 * 1024 * 1;
    bip::file_mapping::remove(fileName.c_str());

    p_file_vec = new bip::managed_mapped_file(bip::create_only, fileName.c_str(), fileSize);
    vecObj = p_file_vec->construct<intVec>("myVecName")(p_file_vec->get_allocator<int>());
    for (size_t i = 0; i < 10; i++)
    {
        vecObj->push_back(1 + 100);
    }
    p_file_vec->flush();

    try
    {   //Fail when execute on Windows(WSL),but Success on Linux(Ubuntu17.10).
        std::cout << "try to shrink:pointer has existed yet!" << std::endl;
        bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
        std::cout << "success to shrink!" << std::endl;
    }
    catch (const boost::interprocess::interprocess_exception  &ex)
    {
        std::cerr << "fail to shrink!" << std::endl;
        std::cerr << ex.what() << std::endl;;
    }
    std::cout <<"please pless enter key."<< std::endl;
    std::cin.get();

    try
    {   //Success when execute on Windows(WSL) and Linux(Ubuntu17.10).
        delete p_file_vec;
        std::cout << "try to shrink:pointer has deleted!" << std::endl;
        bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
        std::cout << "success to shrink!" << std::endl;
    }
    catch (const std::exception& ex)
    {
        std::cerr << "fail to shrink!" << std::endl;
        std::cerr << ex.what() << std::endl;;
    }
    std::cout << "please pless enter key." << std::endl;
    std::cin.get();
}

最佳答案

不要在 C++ 中使用 newdelete(经验法则)。

除此之外

    delete p_file_vec;

不会删除任何物理内容。它有效地断开了与映射文件的连接。这也是 shr​​ink_to_fit 起作用的原因:the documentation explicitly says :

If the application can find a moment where no process is attached it can grow or shrink to fit the managed segment.

here

enter image description here

因此,简而言之:该行为在两个平台上都是正确的。当您在使用映射文件时(在 Ubuntu 上)缩小时,您的情况只是不确定会发生什么。

固定代码:

Live On Coliru

#include <boost/interprocess/managed_mapped_file.hpp>
#include <iostream>
#include <vector>

namespace bip = boost::interprocess;
using intAlloc = bip::allocator<int, bip::managed_mapped_file::segment_manager>;
using intVec = std::vector<int, intAlloc>;

int main() {
    std::string const fileName = "tmp.dat";
    bip::file_mapping::remove(fileName.c_str());

    {
        bip::managed_mapped_file file_vec(bip::create_only, fileName.c_str(), 1l << 20);
        auto *vecObj = file_vec.construct<intVec>("myVecName")(file_vec.get_allocator<int>());

        for (size_t i = 0; i < 10; i++) {
            vecObj->push_back(1 + 100);
        }
    }

    try { // Success when execute on Windows(WSL) and Linux(Ubuntu17.10).
        std::cout << "try to shrink:pointer has deleted!" << std::endl;
        bip::managed_mapped_file::shrink_to_fit(fileName.c_str());
        std::cout << "success to shrink!" << std::endl;
    } catch (const std::exception &ex) {
        std::cerr << "fail to shrink!" << std::endl;
        std::cerr << ex.what() << std::endl;
        ;
    }
}

关于c++ - 为什么 boost 的 managed_mapped_file::shrink_to_fit 在 Windows 和 Linux 上表现不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46970879/

相关文章:

C++ 模板和字符串文字

c++ - C++ 程序员应该避免 memset 吗?

C++ 是否有任何线程安全的组件可以写入(比没有锁的线程安全类似物更快)?

python - 如何获取或查看xgboost的梯度统计值?

c++ - 比较两个不同的 boost::iterator_facade 迭代器

c++ - 如何从 C++ 访问特定 QML 控件的事件

html - 在linux终端通过google chrome/chromium下载网页

java - 将 json 输出作为参数传递给 java 中的 linux 程序

linux - linux ssd + hdd上的文件访问

c++ - Boost 突然进入我的命名空间,声称缺少函数的错误