Python Process.join()和队列don';我不能和大数字打交道

Python Process.join()和队列don';我不能和大数字打交道,python,python-2.7,python-multiprocessing,Python,Python 2.7,Python Multiprocessing,我正在尝试拆分为循环,即 N = 1000000 for i in xrange(N): #do something 使用多处理。过程,它适用于较小的N值。 当我使用更大的N值时,问题就出现了。在p.join()之前或期间发生了一些奇怪的事情,程序没有响应。如果我在函数f的定义中使用print I,而不是q.put(I),那么一切都很好 我将感谢任何帮助。这是代码 from multiprocessing import Process, Queue def f(q,nMin, nMa

我正在尝试拆分为循环,即

N = 1000000
for i in xrange(N):
    #do something
使用多处理。过程,它适用于较小的N值。 当我使用更大的N值时,问题就出现了。在p.join()之前或期间发生了一些奇怪的事情,程序没有响应。如果我在函数f的定义中使用print I,而不是q.put(I),那么一切都很好

我将感谢任何帮助。这是代码

from multiprocessing import Process, Queue

def f(q,nMin, nMax): # function for multiprocessing
    for i in xrange(nMin,nMax):
        q.put(i)

if __name__ == '__main__':

    nEntries = 1000000

    nCpu = 10
    nEventsPerCpu = nEntries/nCpu
    processes = []

    q = Queue()

    for i in xrange(nCpu):
        processes.append( Process( target=f, args=(q,i*nEventsPerCpu,(i+1)*nEventsPerCpu) ) )

    for p in processes:
        p.start()

    for p in processes:
        p.join()

    print q.qsize()

您正试图无限制地扩展队列,并且您正在加入一个子进程,该子进程正在等待队列中的空间,因此您的主进程在等待该子进程完成时被暂停,而且永远不会停止

如果在加入之前将数据从队列中拉出,它将正常工作

您可以使用的一种技术如下:

while 1:
    running = any(p.is_alive() for p in processes)
    while not queue.empty():
       process_queue_data()
    if not running:
        break
liveprocs = list(processes)
while liveprocs:
    try:
        while 1:
            process_queue_data(q.get(False))
    except Queue.Empty:
        pass

    time.sleep(0.5)    # Give tasks a chance to put more data in
    if not q.empty():
        continue
    liveprocs = [p for p in liveprocs if p.is_alive()]
根据文档,p.is_alive()应该执行隐式连接,但它似乎也暗示了最佳实践可能是在此之后在所有线程上显式执行连接

编辑:虽然这一点很清楚,但它可能并没有那么出色。如何使其更好地执行将是高度特定于任务和机器的(通常,无论如何,您不应该一次创建那么多进程,除非某些进程在I/O上被阻塞)

除了将进程的数量减少到CPU的数量之外,一些简单的修复方法可以使其更快一些(同样,取决于具体情况),如下所示:

while 1:
    running = any(p.is_alive() for p in processes)
    while not queue.empty():
       process_queue_data()
    if not running:
        break
liveprocs = list(processes)
while liveprocs:
    try:
        while 1:
            process_queue_data(q.get(False))
    except Queue.Empty:
        pass

    time.sleep(0.5)    # Give tasks a chance to put more data in
    if not q.empty():
        continue
    liveprocs = [p for p in liveprocs if p.is_alive()]

我正在将我的脚本发送到一台有30个CPU的机器上,因此有10个进程,我离最大值还有很远的距离。是否还有其他原因需要我减少进程的数量?我正在做一些数据分析(50GB的数据,大约是900万个事件)。我的想法是将数据分成若干部分(例如10个)并使用多处理。如果您有任何建议,我将不胜感激。更多的进程取决于CPU的数量——如果进程有时会停止,甚至超过CPU的数量。你的第一个问题是措辞,我想这可能是一个程序设计问题——没意识到你有一台强大的机器:无论如何,一个度量要考虑的是你得到的加速比单线程的速度要多——如果你用10个进程(不可能)得到10X加速,那太好了!减少进程之间的依赖关系(等待)是关键——正如您所看到的,您必须排空队列。