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



问题

我使用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)

您可以使用共享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可以当工作者调用CCD_ 14时在CCD_。

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

相关内容

  • 没有找到相关文章

最新更新