6

问题

我正在使用 Python 的多处理模块来异步执行函数。我想要做的是能够在每个进程调用和执行时跟踪我的脚本的整体进度def add_print。例如,我希望下面的代码在每次进程运行该函数时添加 1total并打印出值 ( )。1 2 3 ... 18 19 20我的第一次尝试是使用全局变量,但这不起作用。由于该函数是异步调用的,因此每个进程读取total为 0 开始,并独立于其他进程添加 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)
4

1 回答 1

8

您可以使用共享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 在worker进程中做total一个全局变量,所以worker调用的时候total可以在里面访问。add_printadd_print

请注意,进程数不应超过您机器的 CPU 数。如果这样做,多余的子进程将等待 CPU 可用。processes=20所以除非你有 20 个或更多的 CPU,否则不要使用。如果您不提供processes参数,multiprocessing将检测可用的 CPU 数量并为您生成一个包含那么多工作人员的池。任务的数量(例如 的长度nums)通常大大超过 CPU 的数量。没关系; 当工作人员可用时,任务由其中一名工作人员排队和处理。

于 2015-08-03T01:12:36.500 回答