我如何在Python中正确使用多进程

时间:2017-03-10 06:03:21

标签: python python-3.x parallel-processing multiprocessing

我有一个简单的示例问题,我在Python中苦苦挣扎。我正在使用多进程来执行函数" Thread_Test()"将在0到1的间隔内生成一个统一的随机数组,其中包含" Sample_Size"数组中的数据点数。一旦我得到这个例子,我计划生成该过程的多个副本以试图加速代码执行,然后我将在Thread_Test()中放置一组更复杂的计算。只要我将Sample_Size保持在9,000以下,此示例就可以正常工作。随着我将Sample_Size从10增加到8,000,执行时间增加,但是在8,000时代码只需要0.01秒执行。但是,只要我将Sample_Size增加到9,000,代码就会永远执行,永远不会完成计算。造成这种情况的原因是什么?

from multiprocessing import Process, Queue
import queue
import random
import timeit
import numpy as np

def Thread_Test(Sample_Size):
    q.put(np.random.uniform(0,1,Sample_Size))
    return

if __name__ == "__main__":
    Sample_Size = 9000
    q = Queue()
    start = timeit.default_timer()
    p = Process(target=Thread_Test,args=(Sample_Size,))
    p.start()
    p.join()

    result = np.array([])
    while True:
        if not q.empty():
         result = np.append(result,q.get())
        else:
           break
    print (result)

    stop = timeit.default_timer()
    print ('{}{:4.2f}{}'.format("Computer Time: ", stop-start, " seconds"))

1 个答案:

答案 0 :(得分:1)

问题发生的原因是,如果你在子进程中放入队列中的生成器(生产者),你必须保证主进程(使用者)同时获取元素。否则,主进程将在" p.join()"中等待,而子进程在" Queue.put"中等待。因为队列中有太多的元素,没有消费者为新元素腾出更多空间。

作为doc here

Bear in mind that a process that has put items in a queue will wait before terminating until 
all the buffered items are fed by the “feeder” thread to the underlying pipe

所以简单来说,你需要打电话给#34;得到零件"之前" p.join()"。

如果您在子流程工作之前担心主流程退出,您可能会更改下面的代码:

while True:
    # check subprocess running before break
    running = p.is_alive()
    if not q.empty():
        result = np.append(result,q.get())
    else:
        if not running:
            break

整个部分如下:

def Thread_Test(q, Sample_Size):
    q.put(np.random.uniform(0,1,Sample_Size))


if __name__ == "__main__":
    Sample_Size = 9000
    q = Queue()
    start = timeit.default_timer()
    p = Process(target=Thread_Test,args=(q, Sample_Size,))
    p.daemon = True
    p.start()

    result = np.array([])
    while True:
        running = p.is_alive()
        if not q.empty():
            result = np.append(result,q.get())
        else:
            if not running:
                break
    p.join()
    stop = timeit.default_timer()
    print ('{}{:4.2f}{}'.format("Computer Time: ", stop-start, " seconds"))