使用Python的multiprocessing.pool.map操作相同的整数

Aus*_*n A 5 python asynchronous shared-memory multiprocessing shared-state

问题

我正在使用Python的多处理模块来异步执行功能。我想做的是能够跟踪每个进程调用和执行时脚本的总体进度def add_print。例如,我希望下面的代码在每次进程运行该函数时将其加1 total并打印出值(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)
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 6

您可以使用共享的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)
Run Code Online (Sandbox Code Playgroud)

池初始化程序setup为每个辅助子进程调用一次。在辅助进程中setup 创建total一个全局变量,因此total可以add_print在辅助调用时在内部进行访问add_print

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

  • 这正是我要找的。我想说我在文档中错过了这一点,但我什至不知道该模块处理共享状态。另外,请注意处理器设置!对这个答案很满意! (2认同)