[英]Child process hanging multiprocessing
我有一个问题,子进程挂在我的python应用程序中,只有4/16进程完成了所有这些进程,这些进程都添加到了多处理队列中。 https://docs.python.org/3/library/multiprocessing.html#pipes-and-queues根据python文档:
警告
如上所述,如果子进程已将项目放入队列中(并且未使用JoinableQueue.cancel_join_thread),则该进程将不会终止,直到所有缓冲的项目都已刷新到管道中为止。
这意味着,如果您尝试加入该进程,则除非您确定已耗尽所有已放入队列的项目,否则可能会陷入僵局。 同样,如果子进程是非守护进程,则当父进程尝试加入其所有非守护进程子进程时,其父进程可能会在退出时挂起。
请注意,使用管理器创建的队列不存在此问题。 请参阅编程准则。
我相信这可能是我的问题,但是我在加入之前在队列中进行了get()操作。 我不确定我还能采取什么其他选择。
def RunInThread(dictionary):
startedProcesses = list()
resultList = list()
output = Queue()
scriptList = ThreadChunk(dictionary, 16) # last number determines how many threads
for item in scriptList:
if __name__ == '__main__':
proc = Process(target=CreateScript, args=(item, output))
startedProcesses.append(proc)
proc.start()
while not output.empty():
resultList.append(output.get())
#we must wait for the processes to finish before continuing
for process in startedProcesses:
process.join()
print "finished"
#defines chunk of data each thread will process
def ThreadChunk(seq, num):
avg = len(seq) / float(num)
out = []
last = 0.0
while last < len(seq):
out.append(seq[int(last):int(last + avg)])
last += avg
return out
def CreateScript(scriptsToGenerate, queue):
start = time.clock()
for script in scriptsToGenerate:
...
queue.put([script['timeInterval'], script['script']])
print time.clock() - start
print "I have finished"
您的代码的问题在于, while not output.empty()
也不可靠 (请参见empty )。 您还可能遇到这样的情况,即在创建的进程完成初始化之前,解释器会命中while not output.empty()
,从而使Queue实际上为空。
由于您确切知道要放入队列中的项目数(即len(dictionnary)
),因此您可以从队列中读取该项目数:
def RunInThread(dictionary):
startedProcesses = list()
output = Queue()
scriptList = ThreadChunk(dictionary, 16) # last number determines how many threads
for item in scriptList:
proc = Process(target=CreateScript, args=(item, output))
startedProcesses.append(proc)
proc.start()
resultList = [output.get() for _ in xrange(len(dictionary))]
#we must wait for the processes to finish before continuing
for process in startedProcesses:
process.join()
print "finished"
如果在某个时候您正在修改脚本而又不知道将产生多少项目,则可以使用Queue.get
并设置合理的超时时间:
def RunInThread(dictionary):
startedProcesses = list()
resultList = list()
output = Queue()
scriptList = ThreadChunk(dictionary, 16) # last number determines how many threads
for item in scriptList:
proc = Process(target=CreateScript, args=(item, output))
startedProcesses.append(proc)
proc.start()
try:
while True:
resultList.append(output.get(True, 2)) # block for a 2 seconds timeout, just in case
except queue.Empty:
pass # no more items produced
#we must wait for the processes to finish before continuing
for process in startedProcesses:
process.join()
print "finished"
您可能需要根据CreateScript
计算的实际时间来调整超时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.