【问题标题】:How do you conserve memory when receiving messages from POSIX queues?从 POSIX 队列接收消息时如何节省内存?
【发布时间】:2011-06-25 13:19:51
【问题描述】:

在接收来自 POSIX 队列的消息时如何节省内存?

似乎在多进程/多线程环境中使用 POSIX 队列时,没有线程安全的方法可以将消息出列到小于 max_msgsize 的缓冲区中。

对于这个问题有任何标准解决方案吗?或者它甚至是一个问题?

我很清楚还有其他非常棒的库可以做到这一点,但我只想为不想处理依赖关系的用户提供一个完全标准的解决方案。

仅供参考,我正在尝试为每条消息排队数百兆字节,并拥有一个进程池,其中包含多个线程,每个线程都将消息出列以进行处理。

谢谢, 陈兹

【问题讨论】:

  • 为什么不能只使用信号量来保护访问?也许我不太明白这个问题。
  • 无法查询队列中下一条消息的大小,所以我必须分配一个等于消息允许的最大大小的缓冲区。

标签: c posix memory-management message-queue


【解决方案1】:

正如您所注意到的,POSIX 队列接口不允许您查询消息的大小。

因此,实际上,所有消息都可能是队列定义所配置的最大大小,您必须假设一个简单的实现很可能会利用它来简化记录。

正如你所说,鉴于您正在处理数兆字节的消息,将这些消息放入队列不太可能是一个好的解决方案(不幸的是)。

如果您的消息率很低(在某些定义中是 low)并且您确实有一个合理的上限,那么请继续尝试。

除此之外,您的下一个最佳选择是将队列用作工作订单队列,而不是工作项队列。您的工作项目可能必须以不同的方式存储在文件中。然后在队列中你有一个漂亮的短文件名,指向要处理的工作项的位置。

祝你好运

【讨论】:

  • 感谢您的建议。我确实喜欢允许 POSIX 接口完成“排队”工作的想法,但排队的只是一个参考。
【解决方案2】:

我认为没有真正好的方法可以做到这一点。这是一个想法,但我想你会发现它由于锁争用而表现不佳:

拥有一个等于最大消息大小的静态缓冲区。因为有一个共享缓冲区,所以现在您的出队过程必须如下所示:

  • 锁定信号量
  • 出列到静态缓冲区
  • 找出消息的实际大小
  • 从静态缓冲区复制到消息实际大小的线程本地缓冲区
  • 解锁信号量

使用静态缓冲区会产生开销,但取决于消息大小的分布,您仍然可能会看到总内存使用量减少。但是,现在您必须处理静态缓冲区的争用问题,这可能会很好,尤其是当几条大消息连续到达时。如果非常大的消息很少见,那么这可能不是一个糟糕的解决方案。

【讨论】:

  • 本地线程缓冲区不会溢出堆栈吗?
  • 当我说“线程本地缓冲区”时,我的意思是范围明智。该堆栈上唯一的东西可能是指向动态分配内存的指针。
猜你喜欢
  • 1970-01-01
  • 2011-07-10
  • 1970-01-01
  • 2013-10-10
  • 2016-06-03
  • 2012-11-16
  • 2019-03-17
  • 2010-09-19
  • 2020-11-27
相关资源
最近更新 更多