问题
我使用Python的多处理模块异步执行函数。我想要做的是能够跟踪每个进程调用并执行def add_print
时脚本的整体进度。例如,我希望下面的代码向total
添加1,并在每次进程运行该函数时打印出值(1 2 3 ... 18 19 20
)。我的第一次尝试是使用全局变量但这没有用。由于函数是异步调用的,因此每个进程将total
读为0以启动,并独立于其他进程添加1。因此输出为20 1
而不是递增值。
我怎么能以同步的方式从映射函数引用相同的内存块,即使该函数是异步运行的?我有一个想法是以某种方式将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)
答案 0 :(得分:4)
您可以使用shared Value
:
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)
池初始化程序为每个工作程序子进程调用setup
一次。 setup
使total
成为工作进程中的全局变量,因此total
可以
当工作人员调用add_print
时,在add_print
内访问。
请注意,进程数不应超过计算机的CPU数。如果这样做,多余的子进程将等待CPU变为可用。因此,除非您有20个或更多CPU,否则不要使用processes=20
。如果您没有提供processes
参数,multiprocessing
将检测可用的CPU数量,并为您生成具有该工作人员数量的池。任务数量(例如nums
的长度)通常大大超过CPU的数量。没关系;当一名工人变得可用时,任务由一名工人排队和处理。