清空多处理队列的最佳方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清空多处理队列的最佳方法相关的知识,希望对你有一定的参考价值。

我有几个进程接收数据包并将其转储到一个公共队列中。主进程每秒检查一次队列,获取所有可用的数据包并进行处理。

将所有项目从队列中拉出的最安全方法是什么?我尝试了几种方法,但它们似乎都存在问题。

方法1-非阻塞获取

packets = []
while True:
    try:
        packets.append(queue.get(block=False))
    except Queue.Empty:
        break

方法1存在一个问题,即使队列中仍有剩余数据包,queue.get(block=False)似乎也会提高Queue.Error。我认为如果无法立即获得锁,就会发生这种情况。最终结果是,队列仅被部分清空,而queue.qsize()显示队列中还有更多等待。随着程序运行,队列中的数据包数量继续增长,并且处理滞后。我可以通过每秒将队列清空4至5次以上来解决此问题,但我无法控制数据包的传入速率,因此我不确定这是否是永久解决方案。

方法2-阻止获取

packets = []
while True:
    try:
        packets.append(queue.get(block=True, timeout=0.01))
    except Queue.Empty:
        break

方法2解决了队列增长的问题,但是还有另一个问题,清空队列需要相对较长的时间。我还担心,如果参与进程始终在超时到期之前将数据包转储到队列中,则此循环可能永远不会退出。

最佳方法是什么?

答案

您能做点什么吗?>>

packets = []
while failures < 3:
    try:
        packets.append(queue.get(block=False))
        failures = 0
    except Queue.Empty:
        failures += 1
        time.sleep(0.01)

或者可能更好

while not queue.empty():
    try:
        packets.append(queue.get(block=False))
    except Queue.Empty:
        time.sleep(0.01)

以上是关于清空多处理队列的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

清空队列时遇到问题

C#多线程处理多个队列数据的方法

JMS 队列上多线程消息处理的最佳实践

METAL顶点/片段着色器“拦截”结果的最佳方法

将数据库表用作作业队列(a.k.a批处理队列或消息队列)的最佳方法

消息队列最佳实践消息恰好被消费一次