【发布时间】:2014-07-29 22:11:46
【问题描述】:
我正在尝试使用 boost 的共享内存功能将向量放入共享内存中,正如 this boost article 所讨论的那样。
它大部分都可以工作,除了有时,当我启动并且共享内存段已经存在时,managed_shared_memory::find 会挂起。
调试器显示它卡在 boost::interprocess 内部的某个进程间互斥体上。
我已经检查过了,我没有其他进程会挂在这个共享内存上。
如果按照我的代码进行测试,则测试开始,如果发现该段已存在,则调用 destroyMyShm()。 destroyMyShm() 打开该段并尝试在应该位于该段内的向量上调用 managed_shared_memory::find() 。此查找挂起。
请注意,如果我只是调用 shared_memory_object::remove() 一切正常。我不知道这是否会导致泄漏,因为矢量不会被正确销毁。
对此我有什么办法吗?可能是 boost 中的错误?
只调用 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 (...) {}
}
【问题讨论】:
标签: c++ boost ipc shared-memory