如何在不使用全局变量的情况下与 multiprocessing.Pool 的工人共享内存?

How to share the memory with multiprocessing.Pool's workers, without using global variables?

有两个函数:

def tibidam(..., foo_dyn, index):
    print("(" + str(index) + ") B:", foo_dyn)

    for i in range(...):
        for j ...
            if j not in foo_dyn:
                foo_dyn[ep] = j

    print("(" + str(index) + ") A:", foo_dyn)

def tata(..., foo):
    foo_dyn = Array('i', len(foo))
    
    foo_dyn = foo

    with Pool(processes=4) as pool:
        pool.starmap(tibidam, [(..., foo_dyn, i) 
            for i in range(4)])
    
    return foo

输出(格式化):

foo  : [0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11]
(0) B: [0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11]
(1) B: [0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11]
(2) B: [0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11]
(3) B: [0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11]
(0) A: [27, 1,  2,  3,  64, 5,  6,  7,  80, 9,  10, 11]
(2) A: [0,  1,  64, 3,  4,  5,  13, 7,  8,  9,  92, 11]
(3) A: [0,  1,  2,  31, 4,  5,  6,  73, 8,  9,  10, 18]
(1) A: [0,  18, 2,  3,  4,  27, 6,  7,  8,  99, 10, 11]
...

预期输出(格式化):

foo  : [0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11]
(0) B: [0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11]
(1) B: [0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11]
(2) B: [0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11]
(3) B: [0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11]
(0) A: [27, 1,  2,  3,  64, 5,  6,  7,  80, 9,  10, 11]
(2) A: [27, 1,  55, 3,  64, 5,  13, 7,  80, 9,  92, 11]
(3) A: [27, 1,  55, 31, 64, 5,  13, 73, 80, 9,  92, 18]
(1) A: [27, 87, 55, 31, 64, 88, 13, 73, 80, 99, 92, 18]
...

如何在 foo_dyn 更改时更改所有 worker 中的 foo_dyn?似乎 pool.starmap(...) 为每个进程创建了 foo_dyn 的副本...不,我只想将 foo_dyn 传递给池一次。但是,同样,根本不使用全局变量。

AFAIK,multiprocessing.Pool 支持 initializerinitargs 参数:我可以编写自己的初始化程序:

_init(foo):
    global foo_dyn

    foo_dyn = foo

,但它使用了全局变量foo_dyn(顺便说一句,使用_init函数并不能解决问题)。顺便看到几个问题,几乎一样的麻烦。但是,所有解决方案都与使用全局变量相关联。

我找到了解决方案,没有使用全局变量:

from multiprocessing import Pool, Manager

def tibidam(..., foo_dyn, index):
    for i in range(...):
        for j ...
            if j not in foo_dyn:
                foo_dyn[ep] = j

def tata(..., foo):
    foo_dyn = Manager().list(foo)

    with Pool(processes=4) as pool:
        pool.starmap(tibidam, [(..., foo_dyn, i)
            for i in range(4)])

    return foo_dyn

谢谢大家! :>