boost的问题:进程间共享内存

时间:2016-05-26 17:01:45

标签: c++ boost shared-memory interprocess boost-interprocess

我在为两个程序之间的共享内存操作实现boost / interprocess库时遇到了一些麻烦。这是我第一次使用任何共享内存操作,我首先修改了我在此处找到的boost文档中的一些示例代码:(http://www.boost.org/doc/libs/1_41_0/doc/html/interprocess/quick_guide.html)。

修改后的演示效果很好,基本上是这样的:

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.不确定这是否相关,但认为它值得指出(双关语!)。

谢谢, 乙

1 个答案:

答案 0 :(得分:0)

每个人都忽视的问题,包括我自己,都是这个......

因为类型:

std::pair<myDouble*, managed_shared_memory::size_type> valShrX

得到:

valShrX.first

返回指向myDouble的指针,而不是第一个双精度型,它是在以下位置定义的std :: pair的一部分:

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收到一系列的myDouble时没有显示问题价值被打印?在linux中编译时一切正常。为什么呢?