繁体   English   中英

子进程挂式多处理

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM