boost :: interprocess共享内存段函数find()在启动时挂起,如果段已经存在

时间:2014-07-29 22:11:47

标签: c++ boost ipc shared-memory

我正在尝试使用boost的共享内存功能将向量放入共享内存,如this boost article所述。

除了有时,当我启动并且共享内存段已经存在时,大部分都可以工作,managed_shared_memory :: find将挂起。

调试器显示它停留在boost :: interprocess内部的某些进程间互斥锁上。

我已经检查过,我没有其他正在运行的进程挂起到这个共享内存。

如果按照我的代码,测试开始,如果发现已存在的段,则调用destroyMyShm()。 destroyMyShm()打开段并尝试在应该在该段内的向量上调用managed_shared_memory :: find()。这个发现挂起了。

请注意,如果我只是调用shared_memory_object :: remove()一切正常。我不知道这是否会导致泄漏,因为矢量不会被正确销毁。

我能做些什么吗?可能是助推器中的一个错误?

调用shared_memory_object :: remove()并忘记managed_shared_memory :: destroy()是否安全?

#include <gtest/gtest.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>

typedef  boost::interprocess::allocator<std::string, boost::interprocess::managed_shared_memory::segment_manager>  ShmemAllocator;
typedef  boost::interprocess::vector<std::string, ShmemAllocator> MyVector;


static const char *kSharedMemorySegmentName("myseg");
static const char *kSharedMemoryVectorName("myvec");

bool isMyShmCreated();
void  destroyMyShm();
void initMyShm(size_t);

//pardon my google-test method here...
TEST(MyTest, SharedMemoryTest) {
    using namespace boost::interprocess;
    if (isMyShmCreated())
    {
        destroyMyShm();  //hangs in here (see below)
    }
    EXPECT_FALSE(isMyShmCreated());
    initMyShm(1000000);
    EXPECT_TRUE(isMyShmCreated());


    managed_shared_memory segment(open_only, kSharedMemorySegmentName);
    MyVector *vec = segment.find<MyVector>(kSharedMemoryVectorName).first;

    EXPECT_TRUE(vec != 0);
    vec->push_back(std::string("item 1"));
    vec->push_back(std::string("item 2"));


   destroyMyShm();
}


void initMyShm(size_t size) {
    using namespace boost::interprocess;
    if (isMyShmCreated()) {
        log("already created");
    }
    managed_shared_memory segment(open_or_create, kSharedMemorySegmentName, size);
    MyVector *vec = segment.find<MyVector>(kSharedMemoryVectorName).first;
    if (!vec)
    {
        const ShmemAllocator alloc_inst (segment.get_segment_manager());
        segment.construct<MyVector>(kSharedMemoryVectorName)(alloc_inst);
    } else
    {
        vec->clear();
    }
}

bool isMyShmCreated()
{
    using namespace boost::interprocess;
    try
    {
        managed_shared_memory segment(open_only, kSharedMemorySegmentName);
        return segment.check_sanity();
    } catch (const interprocess_exception &ex) {
        std::cout << "managed_shared_memory ex: "  << ex.what();
    }
    catch (const std::exception &ex) {
        std::cout << "managed_shared_memory ex: "  << ex.what();
    }
    catch (const std::string& ex)
    {
        std::cout << "managed_shared_memory ex: "  << ex;
    } catch (...)
    {
        std::cout << "managed_shared_memory ex: ?";
    }
    return false;
}

void destroyMyShm() {
    using namespace boost::interprocess;
    try
    {
        managed_shared_memory segment(open_only, kSharedMemorySegmentName);
        // hangs on segment.find() below:
        if (segment.find<MyVector>(kSharedMemoryVectorName).first)  
            segment.destroy<MyVector>(kSharedMemoryVectorName);
    } catch (...) {}
    try
    {
        shared_memory_object::remove(kSharedMemorySegmentName);
    } catch (...) {}
}

1 个答案:

答案 0 :(得分:2)

你不应该使用basic_string<char, ShmemAllocator>代替string吗?你的vector实际上是容器的容器 - 我认为所有都应该使用共享分配器。 (你需要两个,一个用于字符串 - 字符 - 第二个用于矢量 - 你的特殊字符串)

编辑:名为“Container of Containers”的提升页面末尾有一个链接....阅读它! (我只是在猜测,那个页面证明我是对的。)

<强>链接:
Boost: Creating vectors in shared memory
Boost: Containers of containers