boost的问题:进程间共享内存
Posted
技术标签:
【中文标题】boost的问题:进程间共享内存【英文标题】:problems with boost:interprocess shared memory 【发布时间】:2016-05-26 17:01:45 【问题描述】:我在为两个程序之间的共享内存操作实现 boost/interprocess 库时遇到了一些麻烦。这是我第一次使用任何共享内存操作,我首先修改了我在这里找到的 boost 文档中的一些示例代码:(http://www.boost.org/doc/libs/1_41_0/doc/html/interprocess/quick_guide.html)。
修改后的demo效果不错,基本是这样的:
typedef std::pair<double, int> MyType;
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
MyType *instance = segment.construct<MyType>
("MyType instance") //name of the object
(12.34, 0); //ctor first argument
MyType *instance2 = segment.construct<MyType>
("MyType instance2") //name of the object
(56.78, 0); //ctor first argument
然后在另一个进程中,检索这些变量:
managed_shared_memory segment(open_only, "MySharedMemory");
std::pair<MyType*, managed_shared_memory::size_type> res;
std::pair<MyType*, managed_shared_memory::size_type> res2;
res = segment.find<MyType>("MyType instance");
printf("1: %d, %d\n", res.first, res.second); // show pointer and size
printf("1a: %f\n\n", *res.first); //show double value
res2 = segment.find<MyType>("MyType instance2");
printf("2: %d, %d\n", res2.first, res2.second); // show pointer and size
printf("2a: %f\n", *res2.first); // show double value
好的,看起来一切正常,终端输出是:
1: 196724, 1
1a: 12.340000
2: 196780, 1
2a: 56.780000
问题是当我尝试在另一个(现有)应用程序中复制它时。
据我所知,我所做的一切几乎都是一样的(在语法方面甚至可能是一样的?),但得到了一些不同的和意想不到的结果。
typedef std::pair<double, int> myDouble;
managed_shared_memory segment(create_only, "sharedMemBlock", 65536);
myDouble *valX = segment.construct<myDouble>
("valX")
(1.1, 0);
myDouble *valY = segment.construct<myDouble>
("valY")
(2.2, 0);
myDouble *valZ = segment.construct<myDouble>
("valZ")
(3.3, 0);
并在第二个过程中检索这些值:
managed_shared_memory segment(open_only, "sharedMemBlock");
std::pair<myDouble*, managed_shared_memory::size_type> valShrX;
std::pair<myDouble*, managed_shared_memory::size_type> valShrY;
std::pair<myDouble*, managed_shared_memory::size_type> valShrZ;
valShrX = segment.find<myDouble>("valX");
valShrY = segment.find<myDouble>("valY");
valShrZ = segment.find<myDouble>("valZ");
printf("PtrvalSharedX: %d,PtrvalSharedY: %d, PtrvalSharedZ: %d\n", valShrX.first, valShrY.first, valShrZ.first);
printf("valSharedX: %f, valSharedY: %f, valSharedZ: %f\n\n", *valShrX.first, *valShrY.first, *valShrZ.first);
但结果不是我所期望的,结果是这样的:
PtrvalSharedX: 196724, PtrvalSharedY: 196772, PtrvalSharedZ: 196820
valSharedX: 1.100000, valSharedY: 0.000000, valSharedZ: 2.200000
那么,这里发生了什么?为什么我没有分别获得 valSharedX、valSharedY 和 valSharedZ 的 1.1、2.2 和 3.3?
不知道为什么本质上相同的代码在一个实例中有效,而在另一个实例中无效。我注意到第一个示例中的指针之间的差异 (196780 - 196724) = 56,但在第二个示例中较小 (196772 - 196724) = (196820 - 196772) = 48。不确定这是否相关,但认为它值得指出(双关语!)。
谢谢, 乙
【问题讨论】:
什么是myDouble
?
抱歉,在整理摘录时忘记了这一行。定义与第一个示例中的 MyType 完全相同。 typedef std::pair包括我自己在内的所有人都忽略的问题是……
因为类型:
std::pair<myDouble*, managed_shared_memory::size_type> valShrX
得到:
valShrX.first
返回指向 myDouble 的指针,而不是指向 std::pair 中定义的第一个 double 的指针:
typedef std::pair<double, int> myDouble;
由于 printf 不知道 myDouble 类型到底是什么,并且由于 printf 本身不知道该类型,因此该问题仅在按顺序打印多个值时出现,并且与 myDouble 的大小不匹配双倍。
所以用它自己的 printf 语句打印每个值(就像在第一个代码摘录中一样)工作正常,因为指针 valShrX.first 告诉 printf 从哪里正确开始。即使 valShrX.first 的大小必须包括作为对的一部分的 int,printf 也会打印 %f 并停止。
在第二个代码摘录中,我尝试在同一个 printf 语句中打印共享内存中的所有三个值,因此 std::pair myDouble 的完整大小(包括其中的 double 和 int)被传播并会抵消打印第二个和第三个值。
正确的语句应该只获取 myDouble 对的第一项,即在父对中...换句话说,这是给定我的数据类型的正确 printf 语法:
printf("valSharedX: %f, valSharedY: %f, valSharedZ: %f\n\n", valShrX.first->first, valShrY.first->first, valShrZ.first->first);
因此,我的 printf 语法在两个示例中都不正确,但是在一个语句中打印多个值时 printf 的更具惩罚性的操作是唯一使问题变得明显的情况。
剩下的唯一让我发痒的问题是:为什么这个问题会出现在 Visual Studio 2013 中,但是在 Linux 中编译的相同代码在 printf 的 %f 在一系列正在打印的值?在linux中编译时一切正常。为什么?
【讨论】:
由于 boost::interprocess 示例仅演示了将您的数据放入共享内存中,而没有演示将您的数据从共享内存中取出,我认为这对于其他人来说是相关的 咳嗽咳嗽@sehe.... 对我的问题和答案投赞成票将不胜感激。以上是关于boost的问题:进程间共享内存的主要内容,如果未能解决你的问题,请参考以下文章