共享内存中的队列起作用

时间:2011-12-12 23:43:43

标签: c++ gcc gdb ipc shared-memory

共享内存给我带来了困难,GDB并没有多大帮助。我分配了32KB的共享内存,并使用shmat将其转换为指向struct的指针,其中包含A)bool和B)包含对象的队列一个std::string,三个int和一个bool,以及各种方法。 (我不知道这个俄罗斯套娃结构是不是你应该怎么做,但这是我知道的唯一方法。使用消息队列不是一个选择,而我需要使用多个流程。)

将一个对象推入队列可以正常工作,但是当我尝试推送一个对象时,程序会冻结。没有错误消息,没有任何消息。是什么引起了这个?我怀疑它是否缺乏记忆,但如果是,我需要多少?

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

编辑2:我更改了队列的条目类,因此它不会使用std::string。 (令人尴尬的是,我能够用原语表示数据。)程序仍然在第二次推送()时冻结。

编辑3 我尝试在第一个front()之后立即从同一个队列调用push(),而 it 也冻结了该程序。然而,检查队列中的bool 的值是否正常,因此队列本身有问题。

编辑4:作为一项实验,我在std::queue<int>添加了struct用于共享内存。它显示了相同的行为 - push()只运行一次,然后front()使其冻结。因此,对于我用于队列项目的课程来说,这也不是问题。

This问题表明我不太可能使用std::queue解决这个问题。是这样吗?我应该像它说的那样使用boost吗? (就我而言,我在父进程中执行shmget()shmat()并尝试让两个子进程进行通信,因此它略有不同。)

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

2 个答案:

答案 0 :(得分:5)

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

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

我不知道为什么你的程序会冻结,但它甚至完全毫无意义

答案 1 :(得分: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可能不是最好的 - 理想情况下你也想要一些长度信息)但是你明白了......