使用Python pool.map让多个进程对列表执行操作

我正在尝试启动6个线程,每个线程从列表文件中取出一个项目,将其删除,然后打印该值.

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

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

解决方法:

部分问题在于您没有处理池的多进程性质(请注意,在Python中,MultiThreading由于Global Interpreter Lock而无法获得性能).

你有必要改变原始清单吗?您当前的代码不使用传入的iterable,而是编辑共享的可变对象,这在并发的世界中是危险的.一个简单的解决方案如下:

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))

==&GT除了第一次调用之外,所有内容都按预期打印“True”.

如果将数字或进程设置为2,则它的确定性较低,因为它取决于哪个进程首先实际执行其语句.

上一篇:c# – System.Timer在单独的线程中运行并保持线程限制


下一篇:c# – ThreadPool在调试模式和运行时的行为不同