以下代码不会打印"here"
。问题是什么?
我在我的两台机器上测试了它(Windows 7,Ubuntu 12.10)和
http://www.compileonline.com/execute_python_online.php
在所有情况下都不会打印"here"
。
from multiprocessing import Queue, Process
def runLang(que):
print "start"
myDict=dict()
for i in xrange(10000):
myDict[i]=i
que.put(myDict)
print "finish"
def run(fileToAnalyze):
que=Queue()
processList=[]
dicList=[]
langs= ["chi","eng"]
for lang in langs:
p=Process(target=runLang,args=(que,))
processList.append(p)
p.start()
for p1 in processList:
p1.join()
print "here"
for _ in xrange(len(langs)):
item=que.get()
print item
dicList.append(item)
if __name__=="__main__":
processList = []
for fileToAnalyse in ["abc.txt","def.txt"]:
p=Process(target=run,args=(fileToAnalyse,))
processList.append(p)
p.start()
for p1 in processList:
p1.join()
答案 0 :(得分:14)
这是因为当你put
multiprocessing.Queue
多个项目时,一旦基础Pipe
已满,它们最终会被缓存在内存中。在从Queue
的另一端开始读取某些内容之前,缓冲区不会被刷新,这将允许Pipe
接受更多数据。在Process
个实例的缓冲区已完全刷新到其基础Queue
之前,Pipe
无法终止。这意味着如果你尝试join
一个进程而没有另一个进程/线程在get
上调用Queue
,你可能会陷入僵局。这是mentioned in the docs:
警告强>
如上所述,如果子进程已将项目放入队列(和 它没有使用
JoinableQueue.cancel_join_thread
),然后是那个过程 直到所有缓冲的项目都被刷新为止后才会终止 管。这意味着如果您尝试加入该过程,您可能会陷入僵局 除非您确定所有已放入队列的项目 已被消耗。同样,如果子进程是非守护进程的 然后父进程在尝试加入所有进程时可能会在退出时挂起 非守护儿童。
请注意,使用管理器创建的队列没有此问题。
您可以在清空父级join
之后再调用Queue
来修复此问题:
for _ in xrange(len(langs)):
item = que.get()
print(item)
dicList.append(item)
# join after emptying the queue.
for p in processList:
p.join()
print("here")