我正在尝试启动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))
==>除了第一次调用之外,所有内容都按预期打印“True”.
如果将数字或进程设置为2,则它的确定性较低,因为它取决于哪个进程首先实际执行其语句.