我对多重处理有点陌生。但是,假设我们有如下程序。这个程序似乎运行得很好。现在来回答这个问题。在我看来,我们将同时拥有4个同名的SomeKindOfClass
实例(a
)。怎么可能?此外,这种编程是否存在潜在风险?在
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))
{{{cd2}实际上,每个
multiprocessing
与multiprocessing.dummy
只有继续使用
multiprocessing.dummy
模块,它只是threading
模块的包装器,程序才会工作。您仍然在使用“python线程”(而不是单独的进程)Python线程“共享相同的全局状态”,“进程”不共享。Python线程也共享相同的GIL,因此它们仍然限于一次运行一个Python字节码语句,而进程则可以同时运行Python代码。在如果要将导入更改为
from multiprocessing import Pool
,您会注意到在所有worker完成执行之后,allOutputs
数组保持不变(而且,您可能会收到一个错误,因为您要在全局范围内创建池,您可能应该将其放在main()
函数中)。这是因为multiprocessing
在生成新进程时会生成整个全局状态的新副本。当worker修改全局allOutputs
时,它将修改该初始全局状态的副本。当进程结束时,不会向主进程返回任何内容,并且主进程的全局状态将保持不变。在进程间共享状态
与线程不同,进程不共享相同的内存
如果要在进程之间共享状态,则必须显式声明共享变量并将它们传递给每个进程,或者使用管道或其他方法允许工作进程彼此通信或与主进程通信。在
有几种方法可以做到这一点,但最简单的方法可能是使用
Manager
类您可以在池工作线程内声明类实例,因为每个实例在内存中都有一个单独的位置,这样它们就不会发生冲突。问题是,如果您首先声明一个类实例,然后尝试将该实例传递给多个池工作器。然后每个工作线程都有一个指向内存中相同位置的指针,它将失败(这可以处理,但不是这样)。在
基本上,池工作人员在任何地方都不能有重叠内存。只要工作人员不尝试在某个地方共享内存,或者执行可能导致冲突的操作(比如打印到同一个文件),就不会有任何问题。在
确保它们应该做的任何事情(比如你想打印到文件中,或者添加到某个更大的命名空间中)都会在最后返回结果,然后进行迭代。在
名称
a
仅在work
函数的作用域内是局部的,因此这里没有名称冲突。在内部python将使用一个唯一的标识符来跟踪每个类实例。如果要检查此项,可以使用id
函数检查对象id:我看不出你的代码有任何问题。在
相关问题 更多 >
编程相关推荐