【问题标题】:Message Queue Overflow avoidance消息队列溢出避免
【发布时间】:2015-09-17 09:09:04
【问题描述】:

我正在使用 C++ 中的消息队列模板来排队我的消息,而这恰好是 SIP 消息的队列。我的队列大小是固定的,当我增加消息的速率和数量时,我能够检测到消息队列中的溢出.

我想避免消息队列溢出。因此,如果有人可以指导我在消息队列中使用实用的溢出避免技术,那将很有帮助。

也欢迎提出关于避免流行的 POSIX 消息队列溢出的建议,因为我会从中得到一些想法。

【问题讨论】:

    标签: debugging operating-system pthreads embedded ipc


    【解决方案1】:

    您能够检测到溢出情况,这很棒。接下来,您只需要定义溢出时的行为。通常有两种选择:阻塞或失败。

    溢出失败很明显,阻塞队列需要互斥体和条件变量:

    std::unique_lock<std::mutex> lock(mutex);
    while ( full() ) {
      cond.wait_for(lock, std::chrono::microseconds(milliseconds));
      // TODO: or define a max wait time and fail accordingly.
    };
    add(message);
    return;
    

    当队列被消耗且不再溢出时执行cond.notify_one()

    【讨论】:

    • 如果你检测到溢出,它已经发生了。 OP 正在询问如何避免,这太宽泛了。
    • 我想通过检测溢出,OP 意味着检查队列是否已满,通过检查队列计数器之类的方法,实际上没有发生任何事情。并且在队列满时阻塞或失败确实可以避免溢出。
    • 完全和溢出定义明确。除非更改,否则我将采用 OP 写的内容。请注意,“已满”条件可能已经太晚了,因为可能没有时间停止下一条正在进行的消息。
    【解决方案2】:

    您通常拥有的消息队列不是溢出 - 因为溢出为时已晚。你有类似高水印的东西。 (Low Watermakr 也值得一提,因为当您始终处于 Low Watermark 时,这意味着您的队列可能太长或处理程序太多。

    一旦您达到高水位线,您就会向用户发出信号。您还可以实施多种策略,具体取决于消息的语义。例如,您可能会开始跳过每第二条消息。您可能会使用“溢出缓冲区” - 非常轻量级的处理程序,它将简单地从队列中读取所有消息并将它们存储在某种缓冲区中,可能像文件一样简单,以供以后处理。你可能会做很多事情,但同样,你是在高水位上做的,而不是在队列已经满的时候。

    【讨论】: