在python中使用池进行多处理:关于同时具有相同名称的多个实例

我对多处理有点新意.但是,假设我们有一个程序如下.该程序似乎工作正常.现在回答这个问题.在我看来,我们将同时具有4个具有相同名称(a)的SomeKindOfClass实例.怎么可能?此外,这种编程是否存在潜在风险?

from multiprocessing.dummy import Pool
import numpy
from theFile import someKindOfClass

n = 8 
allOutputs = numpy.zeros(n)

def work(index):   
    a = SomeKindOfClass()
    a.theSlowFunction()
    allOutputs[index] = a.output

pool = Pool(processes=4) 
pool.map(work,range(0,n))
最佳答案
实际上,你将有8个SomeKindOfClass实例(每个工作一个实例),但只有4个实例同时处于活动状态.

多处理与多处理.dummy

只有在继续使用multiprocessing.dummy模块时,您的程序才有效,该模块只是线程模块的包装器.您仍在使用“python线程”(不是单独的进程). “Python线程”共享相同的全局状态; “进程”没有. Python线程也共享相同的GIL,因此它们仍然仅限于一次运行一个python字节码语句,这与可以同时运行python代码的进程不同.

如果您要将导入更改为多处理导入池,您会注意到allOutputs数组在所有工作程序完成执行后保持不变(同样,您可能会因为您在全局范围内创建池而得到错误,应该把它放在main()函数中).这是因为多处理在创建新进程时会创建整个全局状态的新副本.当worker修改全局allOutputs时,它将修改该初始全局状态的副本.当进程结束时,不会将任何内容返回到主进程,主进程的全局状态将保持不变.

在进程之间共享状态

与线程不同,进程不共享相同的内存

如果要在进程之间共享状态,则必须显式声明共享变量并将它们传递给每个进程,或者使用管道或其他方法来允许工作进程相互通信或与主进程通信.

有几种方法可以做到这一点,但也许最简单的方法是使用Manager类

import multiprocessing

def worker(args):
    index, array = args
    a = SomeKindOfClass()
    a.some_expensive_function()
    array[index] = a.output


def main():
    n = 8
    manager = multiprocessing.Manager()
    array = manager.list([0] * n)
    pool = multiprocessing.Pool(4)
    pool.map(worker, [(i, array) for i in range(n)])
    print array

转载注明原文:在python中使用池进行多处理:关于同时具有相同名称的多个实例 - 代码日志