我使用boost::interprocess
运行最简单的进程间通信程序设置:
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cstdlib> //system
#include <iostream>
using namespace std;
using namespace boost::interprocess;
typedef pair<double, int> MyType;
int main(int argc, char *argv[]) {
if (argc==1) { //Parent process
struct shm_remove {
shm_remove() {shared_memory_object::remove("MySharedMemory");}
~shm_remove() {shared_memory_object::remove("MySharedMemory");}
} remover;
managed_shared_memory segment(create_only,"MySharedMemory",65536);
MyType* instance=segment.construct<MyType>("MyType instance")(0.5,2);
string s(argv[0]);
s+=" child ";
if(system(s.c_str())!=0) {
cout<<"Parent: Child process returned non-zero"<<endl;
return 1;
}
cout<<"Parent: Child process finished successfully"<<endl;
segment.destroy<MyType>("MyType instance");
} else { //Child process
pair<MyType*, managed_shared_memory::size_type> res;
// try {
managed_shared_memory segment(open_only, "MySharedMemory");
res=segment.find<MyType>("MyType instance");
// } catch (interprocess_exception &e) {
// cerr<<"Error while opening the segment"<<endl;
// return 1;
// }
cout<<"Child: Segment of length "<<res.second<<" is found at "<<res.first<<endl;
cout<<"Child: "<<res.first->first<<", "<<res.first->second<<endl;
}
return 0;
}
这有效,我看到了:
Child: Segment of length 1 is found at 0x106a15148
Child: 0.5, 2
Parent: Child process finished successfully
但是,当我取消注释try-catch
块时,我会看到以下内容:
Child: Segment of length 1 is found at 0x10a8fd148
Parent: Child process returned non-zero
如果我将二进制文件拆分为两个(生成段并且永远处于睡眠状态的父级和段读取子级),它将在没有try-cacth
的情况下再次工作,但是使用它时,孩子会崩溃
Segmentation fault: 11
因此,我有两个问题:
try-catch
的原因是什么?它的行为就像块有自己的地址空间一样。但为什么会这样呢?修改
我已将块更改为:
if (1) {
managed_shared_memory segment(open_only, "MySharedMemory");
res=segment.find<MyType>("MyType instance");
cout<<"Child: Segment of length "<<res.second<<" is found at "<<res.first<<endl;
cout<<"Child: "<<res.first->first<<", "<<res.first->second<<endl;
}
我收到同样的错误:
Child: Segment of length 1 is found at 0x108c15148
Child: 0.5, 2
Child: Segment of length 1 is found at 0x108c15148
Parent: Child process returned non-zero
因此,行为确实是由{}
引起的,可能是由于segment
的破坏。但是,如果res.first
已经填充了正确的指针,为什么会这么重要?
答案 0 :(得分:1)
问题似乎是调用了managed_shared_memory
的析构函数,但是在try catch块之后你继续依赖它所持有的状态或分配。
managed_shared_memory segment;
回想一下,析取函数总是在作用域的末尾调用(基本上是任何结束}
),这也适用于try块。
如果这不是``main`函数,那么让异常转义给调用者(没有尝试catch)或者重新抛出它(或者是另一个异常)可能会更好:
try {
managed_shared_memory segment(open_only, "MySharedMemory");
res=segment.find<MyType>("MyType instance");
cout<<"Child: Segment of length "<<res.second<<" is found at "<<res.first<<endl;
cout<<"Child: "<<res.first->first<<", "<<res.first->second<<endl;
} catch (interprocess_exception &e) {
cerr<<"Error while opening the segment"<<endl;
throw;
}
确实,请看the documentation
托管内存段最重要的服务是:
分段内存部分的动态分配。
在内存段中构建C ++对象。这些对象可以是匿名的,也可以将名称与它们关联起来。
搜索命名对象的功能。
自定义许多功能:内存分配算法,索引类型或字符类型。
原子结构和破坏,如果在两个进程之间共享该段,则无法创建两个对象
与同名相关联,简化了同步。