2011-12-12 71 views
0

共享内存给我一个很难的时间,GDB没有太大的帮助。我已经分配了32KB共享内存,并且我使用shmat将其转换为指向包含A)a bool和B)包含一个std::string,3个ints和一个bool的对象队列以及各种方法的指针struct 。 (我不知道这个俄罗斯套娃结构是如何做到的,但这是我知道的唯一方法。使用消息队列不是一种选择,我需要使用多个进程。)队列共享内存代理

将一个对象推到队列上工作,但是当我尝试推一秒时,程序冻结。没有错误信息,没有任何东西。这是什么造成的?我怀疑这是缺乏记忆,但如果是这样,我需要多少?

编辑:如果我不清楚 - 队列中的对象是一个类与五个数据成员描述。

编辑2:我改变了队列条目的类别,以便它不使用std::string。 (令人尴尬的是,我能够用原语表示数据。)该程序在第二次push()时仍然冻结。

编辑3:我尝试的第一个push()后会立即调用同一个队列front(),并冻结的程序了。检查 以外的值但是,该队列工作正常,所以它必须在队列本身出现问题。

EDIT 4:作为一个实验,我添加了一个std::queue<int>struct我使用的共享存储器。它表现出相同的行为 - push()曾经工作过,然后front()冻结。所以对于我用于队列项目的类也不是问题。

This问题建议我不可能用std::queue来解决这个问题。是这样吗?我应该使用boost吗? (在我的情况,我在父进程执行shmget()shmat(),并试图让两个子进程进行通信,所以它的略有不同。)

编辑5:当它调用front()其他子进程也冻结。信号量确保在第一次调用push()之后发生这种情况。

+0

其中是分配了“std :: string”的内存?我打赌两个便士,那就是你的问题所在。 – Nim

+0

我们可以看到再现症状的最小,完整的代码吗?我们不知道如何在共享内存上放置'std :: queue',如何使用信号灯等等。 – pilcrow

回答

5

std::string对象放入共享内存段不能可能工作。

它应该适用于单个进程,但只要尝试从第二个进程访问它,就会得到垃圾:字符串将包含指向堆分配数据的指针,并且该指针为只有在分配它的过程中有效。

我不知道你的程序为什么会死机,但它完全是毫无意义的想都没想。

1

正如我在我的评论中所说的,您的问题源于尝试使用内部需要堆分配的对象,该对象应该是自包含的(即不需要进一步动态分配的内存)。

我会调整你的设置,和的std :: string更改为某个固定大小的字符数组,像

// this structure fits nicely into a typical cache line 
struct Message 
{ 
    boost::array<char, 48> some_string; 
    int a, b, c; 
    bool c; 
}; 

现在,当您需要发布队列的东西,字符串的内容复制到some_string。当然,你应该适当地调整字符串(并且boost::array可能不是最好的 - 理想情况下你也想要一些长度信息),但你明白了...

+0

猜测我明白内存分配的工作原理比我想象的还要好。 ^^;它确实看起来像一个_impartial_分析表明避免_heap_会使我更少_misère-y_。 (你怎么估计一个对象将占用的空间量,虽然?) –

+0

使用'sizeof(object)'也许吧? –

+0

在编辑注释后已过了几分钟,我想到了这一点。 -_-我仍然无法让队列正常工作 - std :: queue'基本上是工作的错误工具吗? –