我试图启动 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 中,由于全局解释器锁,多线程不会提高性能)。
您是否需要更改原始列表?您当前的代码不使用传入的可迭代对象,而是编辑一个共享的可变对象,这在并发世界中是危险的。一个简单的解决方案如下:
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,则确定性较低,因为它取决于哪个进程实际首先执行它们的语句。
关于python - 使用Python pool.map 让多个进程对一个列表进行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8626107/