3

我读过 stl 向量不适用于 SYS V 共享内存。但是,如果我使用 POSIX shm_open 然后使用 NULL 的 mmap (mmap(NULL, LARGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0) 并给出比包含我的向量的对象大得多的大小,并且在映射后添加附加项目到向量,除了超过 LARGE_SIZE 空间之外还有其他问题吗?其他相关问题:在最近的 SUSE linux 上是否保证在不相关的进程中映射到相同的起始地址(使用上述语法)时,我的对象将被直接映射并且不执行(系统)复制以实现进程中的更改值(例如在 mmap-ed 时正常打开和正常文件会发生什么情况)?谢谢!

编辑:这是正确的吗?

void* mem = allocate_memory_with_mmap(); // say from a shared region
MyType* ptr = new ( mem ) MyType( args );
ptr.~MyType() //is this really needed?

现在在一个不相关的过程中:

MyType* myptr = (MyType*)fetch_address_from_mmap(...)
myptr->printHelloWorld();
myptr->myvalue = 1; //writes to shared memory
myptr.~MyType() //is this really needed?

现在如果我想释放内存

munmap(address...) //but this done only once, when none of the processes use it any more
4

1 回答 1

4

您错过了这样一个事实,即 STL 向量通常只是 的一个元组(mem pointer, mem size, element count),其中包含对象的实际内存是从allocator模板参数接收的。

将 的实例std::vector放在共享内存中没有任何意义。您可能想改为查看boost::interprocess图书馆。

编辑0:

内存分配和对象构造是两个不同的阶段,尽管组合在一个语句中,如下所示(除非new为 重新定义运算符MyType):

// allocates from process heap and constructs
MyType* ptr = new MyType( args );

您可以使用Placement new拆分这两个阶段:

void* mem = allocate_memory_somehow(); // say from a shared region
MyType* ptr = new ( mem ) MyType( args );

尽管现在您必须显式调用析构函数并释放内存:

ptr->~MyType();
release_memory_back_to_where_it_came_from( ptr );

这本质上就是在 C++ 中如何在共享内存中构造对象。请注意,存储指针的类型不适合共享内存,因为一个进程内存空间中的任何指针在另一个进程内存空间中都没有任何意义。改为使用显式大小和偏移量。

希望这可以帮助。

于 2012-09-26T14:37:38.350 回答