Python多进程冻结问题

5

我正在尝试使用Python实现多进程。当池化非常快的任务时,它可以正常工作,但是当池化较长的任务时会出现冻结。请看下面的示例:

from multiprocessing import Pool
import math
import time

def iter_count(addition):
    print "starting ", addition
    for i in range(1,99999999+addition):
        if i==99999999:  
            print "completed ", addition
            break

if __name__ == '__main__':
    print "starting pooling "
    pool = Pool(processes=2)
    time_start = time.time()
    possibleFactors = range(1,3)   

    try: 
        pool.map( iter_count, possibleFactors)
    except:
        print "exception"

    pool.close()
    pool.join()      

    #iter_count(1)
    #iter_count(2)
    time_end = time.time()
    print "total loading time is : ", round(time_end-time_start, 4)," seconds"

在这个例子中,如果我在for循环中使用较小的数字(例如9999999),它可以正常工作。但是当运行99999999时会卡住。我尝试按顺序运行两个进程(iter_count(1)和iter_count(2)),大约需要28秒,因此不算一个大任务。但是当我将它们汇集起来时,程序就会挂起。我知道Python中有一些已知的多进程问题,然而,在我的情况下,相同的代码适用于较小的子任务,但对于较大的任务会卡住。

1
你使用的是哪个版本的Python?你提到的multiprocessing中的一些已知bug在2.7版本或者之后的2.6.x或2.7.x版本中已经修复了,但是如果你使用的是那些修复之前的版本,显然你仍然会遇到这些bug...而且一般来说,多进程/多线程的bug只会在百万分之一甚至更少的情况下发生,所以如果N通常工作正常,但10N通常失败也不足为奇... - abarnert
我正在使用Python 2.7.5版本。 - hercules.cosmos
1
我记得过去我的工作线程在向标准输出写入大量内容时也遇到了类似的问题。你尝试过移除打印语句吗? - John Greenall
1个回答

6
你正在使用 Python 2 的某个版本 - 我们可以根据 "print" 的拼写方式来确定。所以,range(1,99999999+addition) 将创建一个庞大的列表,至少包含 1 亿个整数。而且你正在同时在两个工作进程中执行这个操作。我敢打赌,你的硬盘正忙于自己磨损,而操作系统则尽可能地交换所有东西。将 "range" 改为 "xrange" 然后看看会发生什么。我打赌那时它就能正常工作了。

当我将range更改为xrange时,它可以工作。然而,我不明白的是:当我按顺序运行这些任务时它是如何工作的,但是当我并行运行它们时会冻结。总的来说,我们并不谈论复杂的计算,两个任务都需要大约30秒。 - hercules.cosmos
7
这与计算毫无关系,完全与峰值内存使用有关。你的程序没有冻结,只是因为内存不足而运行得非常缓慢。如果你按顺序执行它们,它只需要一半的内存。你当时只是幸运罢了。那些巨大的列表需要几个GB的内存。xrange 给你一个迭代器而不是一个巨大的列表,并且只需要极少量的内存。就是这样。 - Tim Peters
1
我喜欢这种问题可以伪装成另一个问题的方式。 - vy32

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接