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

时间:2017-10-27 08:40:18

标签: c++ linux boost

这是关于C ++库的提升。

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

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

这是正确的行为吗?

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

我把示例代码放在下面。

编译环境

  • 升压:version.1.65.1

    • VisualStudio2017
    • WSL(Ubuntu16.04)
  • Linux的

    • UbuntuServer17.10,
    • 铛++ 5.0,
    • 克++ 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();
}

1 个答案:

答案 0 :(得分:1)

请勿在C ++中使用newdelete(经验法则)。

除此之外

    delete p_file_vec;

不删除任何物理内容。它有效地与映射文件断开连接。这也是shrink_to_fit有效的原因:the documentation explicitly says

  

如果应用程序可以找到没有附加进程的时刻,它可以增长或缩小以适应托管段。

here

  

enter image description here

因此,简而言之:两种平台上的行为都是正确的。它只是UNDEFINED当你在使用映射文件时缩小你的情况会发生什么(在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;
        ;
    }
}