我试图使用Boost :: Interprocess来(i)在一个进程中在共享内存中创建一个集合,以及(ii)在另一个进程中打印集合(1,2,3)的值。
这个程序编译,但崩溃了:
#include "stdafx.h"
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/set.hpp>
#include <functional>
#include <utility>
#include <set>
using namespace boost::interprocess;
//Define allocator type
typedef allocator<int, managed_shared_memory::segment_manager> shmAlloc;
//Define set type
typedef set<int,std::less<int>,shmAlloc> mySet;
//Write function
void writer()
{
//Remove shared memory on construction and destruction
struct shm_remove
{
shm_remove() { shared_memory_object::remove("MySharedMemory"); }
~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
} remover;
//Create shared memory object
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
//Initialize the shared memory STL-compatible allocator
shmAlloc alloc_inst(segment.get_segment_manager());
//Construct the set
mySet *myset =
segment.construct<mySet>("MySet")(std::less<int>(),alloc_inst);
//Insert data
myset->insert(3);
myset->insert(1);
myset->insert(2);
}
//Read-and-print function
void reader(){
//Open shared memory object
managed_shared_memory segment(open_only, "MySharedMemory");
//Find the set
mySet *myset = segment.find<mySet>("MySet").first;
//Print set members
for (auto it = myset->begin(); it != myset->end(); ++it)
std::cout << *it;
std::cout << std::endl;
}
int main(){
writer();
reader();
std::cout << "Press any key to continue" << std::endl;
std::cin.ignore();
return 0;
}
如果我将所有内容都抛入writer()函数,我就可以进行写入和打印,因此我知道问题与同步有关。我需要通过2个流程来完成这个任务。
感谢您的帮助。
答案 0 :(得分:0)
将boost::interprocess::interprocess_exception
异常处理添加到reader()
中会显示:
The system cannot find the file specified.
remover
个对象删除了writer()
范围末尾的共享内存文件。如果您将reader()
和writer()
移动到(按照您的计划)他们自己的进程中,代码将起作用,只需要确保编写器进程首先启动并且有足够的时间来创建和填充共享内存文件并最后结束(必须在读取器进程运行时运行)。
或者,你可以在编写器构造中单独调用shm_remove
来替换shared_memory_object::remove("MySharedMemory");
struct,然后你的当前示例没有问题。在2个进程场景中,当您需要使用reader时,您不需要让编写器一直运行。请记住,共享内存文件不会在编写器销毁时被删除,并且会一直保留,如果文件很大,则可能不会很好。