2011-12-24 73 views
3

我试图启动6个线程,每个从列表文件中取出一个项目,将其删除,然后打印值。使用Python pool.map让多个进程在列表上执行操作

from multiprocessing import Pool 

files = ['a','b','c','d','e','f'] 

def convert(file): 
    process_file = files.pop() 
    print process_file 

if __name__ == '__main__': 

    pool = Pool(processes=6) 
    pool.map(convert,range(6)) 

预期输出应该是:

a 
b 
c 
d 
e 
f 

相反,输出是:

f 
f 
f 
f 
f 
f 

这是怎么回事?提前致谢。

回答

4

问题的部分原因是您没有处理池的多进程特性(请注意,在Python中,由于全局解释器锁,MultiThreading不能获得性能)。

是否有原因需要更改原始列表?您当前的代码不使用传入的迭代器,而是编辑共享的可变对象,这在并发领域是危险的。一个简单的解决办法如下:

from multiprocessing import Pool 

files = ['a','b','c','d','e','f'] 

def convert(aFile): 
    print aFile 

if __name__ == '__main__': 

    pool = Pool() #note the default will use the optimal number of workers 
    pool.map(convert,files) 

你的问题真让我思考,所以我做了一些更多的探索理解,为什么Python中这样的行为。看起来,Python正在做一些有趣的黑魔法和深刻复制(同时保持id,这是非标准的)对象到新进程中。这可以通过改变所使用的数或过程中可以看出:

from multiprocessing import Pool 

files = ['d','e','f','a','b','c',] 

a = sorted(files) 
def convert(_): 
    print a == files 
    files.sort() 
    #print id(files) #note this is the same for every process, which is interesting 

if __name__ == '__main__': 

    pool = Pool(processes=1) # 
    pool.map(convert,range(6)) 

==>所有,但在第一次调用打印“真”如预期。

如果将数量或进程设置为2,则它不太确定,因为它取决于哪个进程首先实际执行其语句。

+0

这正是我所期待的。感谢您帮助我理解Pool.map函数。 – ensnare 2011-12-24 18:57:45

相关问题