使用Python';s multiprocessing.pool.map来处理相同的整数
问题 我使用Python的多处理模块异步执行函数。我想做的是能够在每个进程调用和执行使用Python';s multiprocessing.pool.map来处理相同的整数,python,asynchronous,multiprocessing,shared-memory,shared-state,Python,Asynchronous,Multiprocessing,Shared Memory,Shared State,问题 我使用Python的多处理模块异步执行函数。我想做的是能够在每个进程调用和执行def add_print时跟踪脚本的总体进度。例如,我希望下面的代码将1添加到total,并在每次进程运行该函数时打印出值(12318 19 20)。我的第一次尝试是使用全局变量,但没有成功。由于函数是异步调用的,因此每个进程从0开始读取total,并独立于其他进程添加1。因此,输出是201,而不是递增值 即使函数是异步运行的,我怎么能以同步方式从映射函数中引用相同的内存块呢?我的一个想法是以某种方式将tota
def add_print
时跟踪脚本的总体进度。例如,我希望下面的代码将1添加到total
,并在每次进程运行该函数时打印出值(12318 19 20
)。我的第一次尝试是使用全局变量,但没有成功。由于函数是异步调用的,因此每个进程从0开始读取total
,并独立于其他进程添加1。因此,输出是201
,而不是递增值
即使函数是异步运行的,我怎么能以同步方式从映射函数中引用相同的内存块呢?我的一个想法是以某种方式将total
缓存在内存中,然后在添加到total
时引用该内存块。在python中,这是一种可行且基本合理的方法吗
请让我知道,如果你需要更多的信息或如果我没有解释的东西不够好
谢谢
代码
#!/usr/bin/python
## Import builtins
from multiprocessing import Pool
total = 0
def add_print(num):
global total
total += 1
print total
if __name__ == "__main__":
nums = range(20)
pool = Pool(processes=20)
pool.map(add_print, nums)
您可以使用:
池初始值设定项为每个辅助进程调用一次setup
<代码>设置
使total
成为工作进程中的全局变量,因此可以
当工作人员调用add\u print
时,可在add\u print
内访问
注意,进程数不应超过您的计算机拥有的CPU数。如果这样做,多余的子进程将等待CPU可用。因此,除非您有20个或更多CPU,否则不要使用
进程=20
。如果不提供进程
参数,多处理
将检测可用CPU的数量,并为您生成一个包含这么多工作线程的池。任务的数量(例如nums
的长度)通常大大超过CPU的数量。那很好;当工作人员可用时,任务将由其中一个工作人员排队和处理。执行类似操作(为进度设置全局变量等)会强制同步,因此可能会限制您的性能。如果您有足够大的工作单元并且很少更新变量,则不太可能。在一个紧密的循环中做这件事可能会让你跛脚。这正是我想要的。我想说的是,我在文档中遗漏了这一点,但我从未意识到该模块处理共享状态。另外,请注意处理器设置!有了这个答案,我再高兴不过了!在仔细考虑了一下您的答案之后,我注意到设置processes=8
和processes=20
在行为上有明显的不同。根据您的解释,听起来这两种设置应该导致相同的操作。不是这样吗?顺便说一下,我有8个CPU。如果你使用的是Windows,我应该提到这将在OSX和Ubuntu上使用。你不会很容易面临竞争条件吗?
import multiprocessing as mp
def add_print(num):
"""
https://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessing
"""
with lock:
total.value += 1
print(total.value)
def setup(t, l):
global total, lock
total = t
lock = l
if __name__ == "__main__":
total = mp.Value('i', 0)
lock = mp.Lock()
nums = range(20)
pool = mp.Pool(initializer=setup, initargs=[total, lock])
pool.map(add_print, nums)