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

标签 python threadpool

我试图启动 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/

相关文章:

c++ - 绑定(bind)返回值和可变参数模板

python - "i"语句中的 "for"变量在函数内部有效吗?

java - 将旧的线程池代码升级到新的并发类

java - 预定执行器服务 : when shutdown should be invoked?

python - 如果满足条件,则使用自定义函数应用于 df 列

java - 如何在一个线程处于 sleep 模式时实现多线程

Java 线程 - 奇怪的 Thread.interrupted() 和 future.cancel(true) 行为

Python 使用动态比较说明符比较版本号

python - 如何在下面的代码中显示行和列的索引

python - 将一维列表转换为二维列表(写入错误)