多处理池中的全局变量

2024-07-05 12:30:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道这个问题以前在这里讨论过,但我就是找不到任何有效的方法。 我想在我的多处理进程之间共享一个全局变量,而不需要任何进程更改它,即它们只需要读取访问。举一个简单的例子:

    def f(x):
        return x**GlobalVar

    if __name__ == '__main__':
        GlobalVar = 6
        pool = multiprocessing.Pool()
        res= pool.map(f,[1,2,3,4])
        print(res)

现在这显然不起作用,因为进程将无法访问GlobalVar。因此,为了让它发挥作用,我会在每个单独的过程中评估GlobalVar,或者从文件导入它。在我的应用程序中,GlobalVar是一个非常大的数组,这是非常浪费的。如何在进程之间轻松共享这个全局变量,而只在内存中存储它的一个副本?我想重申,流程只需要读取这个全局变量,而不需要更改它


Tags: 方法namemapreturnif进程maindef
2条回答

由于要共享的变量为只读且为“简单”整数,因此只需在全局范围内声明它,使多处理池中的子进程可以看到它:

import multiprocessing

GlobalVar = 6

def f(x):
    return x**GlobalVar

if __name__ == '__main__':
    pool = multiprocessing.Pool()
    res= pool.map(f,[1,2,3,4])
    print(res)

印刷品:

[1, 64, 729, 4096]

讨论

在讨论Python和多处理时,您在哪个平台上运行总是相关的,我已经更新了您的标记以添加Windows(尽管现在编写的代码也可以在Linux上运行)

在创建新进程(或创建进程池时的进程)的Windows上,使用spawn。这意味着新进程不会继承主进程建立的变量,而是为每个新进程启动一个新的Python解释器,并从程序顶部开始执行。这就是为什么必须将启动新进程的代码封装在if __name__ == '__main__':块中,否则将进入递归循环。但是由于这个原因,您必须将GlobalVar的声明移动到全局范围,否则将不会为新创建的进程定义该变量

为池中的每个子进程初始化全局变量的另一种方法是使用池初始值设定项函数,它使您能够执行比这更详细的操作:

import multiprocessing

def init_pool(the_int):
    global GlobalVar
    GlobalVar = the_int

def f(x):
    return x**GlobalVar

if __name__ == '__main__':
    GlobalVar = 6
    pool = multiprocessing.Pool(initializer=init_pool, initargs=(GlobalVar,))
    res= pool.map(f,[1,2,3,4])
    print(res)

非常简单的方法是将其作为参数传递给在每个进程中执行的f。但是如果全局变量太大,并且您不希望在每个进程中都有它的副本,并且您只打算执行读取操作,那么您可以使用共享内存

样本(内联记录)

from multiprocessing import Pool
from multiprocessing import shared_memory
import numpy as np
def f(x):
    # Attach to the existing shared memory
    existing_shm = shared_memory.SharedMemory(name='abc123')
    # Read from the shared memory (we know the size is 1)
    c = np.ndarray((1,), dtype=np.int64, buffer=existing_shm.buf)
    return x*c[0]

if __name__ == '__main__':
    a = np.array([6])
    # Creates shared memory with name abc123
    shm = shared_memory.SharedMemory(create=True, size=a.nbytes, name="abc123")
    # Create numpy array backed by shared memory
    b = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)
    # copy the data into shared memory
    b[:] = a[:]
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))

输出:

[6, 12, 18]

查找官方文件here

相关问题 更多 >