我对理解队列中的队列有疑问multiprocessing
python 3中的模块
这就是他们在编程指南:
请记住,已将项目放入队列的进程将在之前等待
终止,直到所有缓冲的项目都被“feeder”线程送入
底层管道。 (子进程可以调用
Queue.cancel_join_thread
队列的方法来避免这种行为。)
这意味着每当您使用队列时,您都需要确保所有
已放入队列的项目最终将在
进程已加入。否则你无法确定哪些进程有
将项目放入队列将终止。还要记住非守护进程
进程将自动加入。
会出现死锁的示例如下:
from multiprocessing import Process, Queue
def f(q):
q.put('X' * 1000000)
if __name__ == '__main__':
queue = Queue()
p = Process(target=f, args=(queue,))
p.start()
p.join() # this deadlocks
obj = queue.get()
这里的修复方法是交换最后两行(或者简单地删除
p.join() 行)。
所以显然,queue.get()
不应在 a 之后调用join()
.
然而,有一些使用队列的例子,其中get
在 a 之后调用join
like:
import multiprocessing as mp
import random
import string
# define a example function
def rand_string(length, output):
""" Generates a random string of numbers, lower- and uppercase chars. """
rand_str = ''.join(random.choice(
string.ascii_lowercase
+ string.ascii_uppercase
+ string.digits)
for i in range(length))
output.put(rand_str)
if __name__ == "__main__":
# Define an output queue
output = mp.Queue()
# Setup a list of processes that we want to run
processes = [mp.Process(target=rand_string, args=(5, output))
for x in range(2)]
# Run processes
for p in processes:
p.start()
# Exit the completed processes
for p in processes:
p.join()
# Get process results from the output queue
results = [output.get() for p in processes]
print(results)
我已经运行了这个程序并且它可以工作(也作为 StackOverFlow 问题的解决方案发布Python 3 - 多重处理 - Queue.get() 没有响应).
有人可以帮我理解这里僵局的规则是什么吗?
多处理中允许数据在进程之间传输的队列实现依赖于标准操作系统管道。
操作系统管道不是无限长的,因此在操作系统中对数据进行排队的进程可能会被阻塞put()
操作直到其他进程使用get()
从队列中检索数据。
对于少量数据,例如您示例中的数据,主进程可以join()
所有生成的子进程,然后获取数据。这通常运作良好,但无法扩展,并且不清楚何时会崩溃。
但它肯定会随着大量数据而崩溃。子进程将被阻塞在put()
等待主进程从队列中删除一些数据get()
,但主进程被阻塞在join()
等待子进程完成。这导致了僵局。
这是一个用户有的示例这个确切的问题。我在那里的答案中发布了一些代码,帮助他解决了他的问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)