python - 如何使用 multiprocessing.Queue.get 方法?
问题描述
下面的代码将三个数字放在一个队列中。然后它尝试从队列中取回号码。但它永远不会。如何从队列中获取数据?
import multiprocessing
queue = multiprocessing.Queue()
for i in range(3):
queue.put(i)
while not queue.empty():
print queue.get()
解决方案
在阅读@Martijn Pieters'之后,我最初删除了这个答案,因为他更详细和更早地描述了“为什么这不起作用”。然后我意识到,OP 示例中的用例不太适合
“如何使用 multiprocessing.Queue.get 方法”。
这并不是因为演示中不涉及子进程,而是因为在实际应用程序中,几乎不会预先填充队列并且仅在之后读取,但是读取和写入发生在中间的等待时间中交错发生。Martijn 展示的扩展演示代码在通常情况下不起作用,因为当排队跟不上读取速度时,while 循环会过早中断。所以这里是重新加载的答案,它能够处理通常的交错提要和读取场景:
不要依赖 queue.empty 检查同步。
将对象放入空队列后,队列的 empty() 方法返回 False 和 get_nowait() 可以在不引发 queue.Empty 的情况下返回之前可能会有一个无限小的延迟。...
空的()
如果队列为空,则返回 True,否则返回 False。由于多线程/多处理语义,这是不可靠的。文档
要么从队列中使用for msg in iter(queue.get, sentinel):
,.get()
通过传递一个哨兵值来打破循环...... iter(callable,sentinel)?
from multiprocessing import Queue
SENTINEL = None
if __name__ == '__main__':
queue = Queue()
for i in [*range(3), SENTINEL]:
queue.put(i)
for msg in iter(queue.get, SENTINEL):
print(msg)
...或者如果您需要非阻塞解决方案,请使用get_nowait()
并处理可能的异常。queue.Empty
from multiprocessing import Queue
from queue import Empty
import time
SENTINEL = None
if __name__ == '__main__':
queue = Queue()
for i in [*range(3), SENTINEL]:
queue.put(i)
while True:
try:
msg = queue.get_nowait()
if msg == SENTINEL:
break
print(msg)
except Empty:
# do other stuff
time.sleep(0.1)
如果只有一个进程且该进程中只有一个线程正在读取队列,则还可以将最后一个代码片段交换为:
while True:
if not queue.empty(): # this is not an atomic operation ...
msg = queue.get() # ... thread could be interrupted in between
if msg == SENTINEL:
break
print(msg)
else:
# do other stuff
time.sleep(0.1)
由于线程可以在检查和之间删除GIL,因此这不适用于进程中的多线程队列读取。如果多个进程正在从队列中读取,这同样适用。if not queue.empty()
queue.get()
不过,对于单一生产者/单一消费者的场景,使用 amultiprocessing.Pipe
而不是multiprocessing.Queue
就足够了,而且性能更高。
推荐阅读
- react-native - 当我发送 localNotification 时,OnNotification() 函数不起作用
- flutter - 嵌套 Firebase GET 请求的颤振错误
- sql - SQL中如何基于一列只聚合几行数据
- python - 如何在 Python 中加载 .mdl 文件?
- xcode - 将应用上传到 Test Flight App Store Connect 后的空构建
- c++ - 我如何将一个列表(或等价物)与 C++ 中的另一个列表进行比较
- excel - 查找 Activecell 表行的 VBA 函数
- python - 使用 QThread 在 pyQt5 中运行 while 循环,在停止按钮上分配 true 和 false
- python - 圆圈没有在正确的位置绘制pygame
- php - 我想使用 BitWasp 库生成 tron 钱包地址