C++ 共享内存中的队列出现问题

C++ 共享内存中的队列出现问题,c++,gcc,gdb,ipc,shared-memory,C++,Gcc,Gdb,Ipc,Shared Memory,共享内存让我很为难,GDB帮不了我多少忙。我已经分配了32KB的共享内存,我使用shmat将它转换为一个指向struct的指针,其中包含abool和B)一个对象队列,其中包含一个std::string,三个int和一个bool,以及各种方法。(我不知道这个matryoshka结构是不是应该这样做,但这是我知道的唯一方法。使用消息队列不是一个选项,我需要使用多个进程。) 将一个对象推到队列上是可行的,但当我尝试推第二个对象时,程序冻结。没有错误消息,什么也没有。这是什么原因造成的?我怀疑这是缺乏记

共享内存让我很为难,GDB帮不了我多少忙。我已经分配了32KB的共享内存,我使用
shmat
将它转换为一个指向
struct
的指针,其中包含a
bool
和B)一个对象队列,其中包含一个
std::string
,三个
int
和一个
bool
,以及各种方法。(我不知道这个matryoshka结构是不是应该这样做,但这是我知道的唯一方法。使用消息队列不是一个选项,我需要使用多个进程。)

将一个对象推到队列上是可行的,但当我尝试推第二个对象时,程序冻结。没有错误消息,什么也没有。这是什么原因造成的?我怀疑这是缺乏记忆,但如果是,我需要多少

编辑:如果我不清楚的话——队列中的对象属于一个类,包含所描述的五个数据成员

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

编辑3:在第一次
push()
之后,我立即尝试从同一队列调用
front()
,它也冻结了程序。但是,在队列外部检查
bool
的值效果很好,因此队列本身肯定有问题

edit4:作为一个实验,我在用于共享内存的
struct
中添加了一个
std::queue
。它显示了相同的行为--
push()
工作一次,然后
front()
使其冻结。因此,我用于队列项目的类也没有问题

问题表明我不太可能用
std::queue
解决这个问题。是这样吗?我应该像上面说的那样使用
boost
?(在我的例子中,我在父进程中执行
shmget()
shmat()
,并试图让两个子进程通信,所以这有点不同。)


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

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

对于单个进程来说,它应该可以正常工作,但一旦您尝试从第二个进程访问它,就会得到垃圾:字符串将包含指向堆分配数据的指针,而该指针仅在分配它的进程中有效


我不知道你的程序为什么会冻结,但想都没用。

std::string
对象放入共享内存段是不可能的

对于单个进程来说,它应该可以正常工作,但一旦您尝试从第二个进程访问它,就会得到垃圾:字符串将包含指向堆分配数据的指针,而该指针仅在分配它的进程中有效


我不知道你的程序为什么会冻结,但想一想都毫无意义。

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

我将调整您的设置,并将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;
};
//此结构非常适合典型的缓存线
结构消息
{
boost::数组一些_字符串;
INTA、b、c;
布尔c;
};

现在,当您需要在队列上发布内容时,将字符串内容复制到
some\u string
。当然,您应该适当地调整字符串的大小(而且
boost::array
可能不是最好的-理想情况下,您也需要一些长度信息),但是您得到了这样的想法…

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

我将调整您的设置,并将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;
};
//此结构非常适合典型的缓存线
结构消息
{
boost::数组一些_字符串;
INTA、b、c;
布尔c;
};

现在,当您需要在队列上发布一些内容时,请将字符串内容复制到
一些字符串中。当然,您应该适当地调整字符串的大小(而且
boost::array
可能不是最好的-理想情况下,您还需要一些长度信息)但是你明白了…

std::string的内存分配在哪里了?我打赌两个便士,这就是你的问题所在。我们可以看到最小的、完整的代码来重现症状吗?我们不知道你是如何将
std::queue
放在共享内存上的,你是如何使用信号量的,等等。你的内存在哪里分配的
std::string
吗?我敢打赌两个便士,这就是你的问题所在。我们可以看看最小的、完整的代码来重现症状吗?我们不知道你是如何将
std::queue
放在共享内存上的,你是如何使用信号量的,等等。我想我对内存分配的理解比我想象的还要差.^^;它确实看起来像是一个公正的分析表明,避免堆会使我的misère-y少很多。(不过,你如何估计一个对象将占用的空间量?)我在几分钟后发现编辑评论已经太晚了。---我仍然无法让队列正常工作-
std::queue
基本上是工作的错误工具吗?@ShayGuy,是的,很可能它下面使用的是
std::deque
,它也有自己的堆分配!你需要使用一些特殊的工具专门设计在一个平台上工作的