了解 Python 中跨进程的静态类变量



我正在使用模块创建不同的守护进程工作线程,其类与其目标相同multiprocessing。此类根据上下文动态导入不同的模块,并将这些模块存储在类范围的静态字典中。我开始思考,由于类级静态字典,所有过去工人(可能已经终止(所做的所有导入是否在所有未来的工人中可用/存在?

所以我调试并意识到这确实没有发生,过去工人的进口并没有像希望的那样成为现在的未来工人。但开始想知道为什么会这样。所以我创建了模仿相同的小例子。下面是两个示例。两者都涉及相同的Cmodule.py,其中包含工作线程的目标类C。区别仅在于temp.py,也仅在于mup.Process()的论证。第一个示例失败,因为过去工作线程添加的类C中的静态字典的成员存在于未来的工作线程中。虽然第二个例子不是这种情况。

Cmodule.py

class C:
staticDict = {}
def __init__(self, condition):
if condition:
C.staticDict['a'] = 'a'
else:
C.staticDict['b'] = 'b'
self.printStaticDict()
def printStaticDict(self):
print(C.staticDict)

示例 1 - temp.py

import multiprocessing as mup
from Cmodule import *
def newProc3():
c = C(True)
def newProc4():
c = C(False)
newProc3Obj = mup.Process(newProc3())
newProc4Obj = mup.Process(newProc4())
newProc3Obj.start()
newProc4Obj.start()

示例 2 - temp.py

import multiprocessing as mup
from Cmodule import *
def newProc3():
c = C(True)
def newProc4():
c = C(False)
newProc3Obj = mup.Process(target=newProc3)  //this differs from example 1
newProc4Obj = mup.Process(target=newProc4)  //this differs from example 1
newProc3Obj.start()
newProc4Obj.start()

示例 1 - 输出

{'a': 'a'}
{'a': 'a', 'b': 'b'}

示例 2 - 输出

{'a': 'a'}
{'b': 'b'}

请注意,在示例 1 输出中,键值'a':'a'保留在第二个工作线程中,但在示例 2 中并非如此。那么,下面两个有什么区别呢?

newProc4Obj = mup.Process(newProc4())

newProc4Obj = mup.Process(target=newProc4)

也可以按照问题第一段中的解释尝试做什么吗?

实际上,您的两个版本之间存在两个很大且非常明显的差异。

在第一个示例中,您调用newProc3newProc4并将这些调用的结果(在本例中为None(作为Processgroup参数传递。

在第二个示例中,您将newProc3/newProc4函数作为target参数传递。

这意味着在第一种情况下,您的newProcX函数都在父进程中执行,这就是为什么您似乎得到了预期的结果 - 但实际上您没有:Process没有目标,因此它们根本不执行任何内容。

第二个示例是设置 Process 的正确方法 - 通过将其作为目标传递一个可调用对象 - 但由于这些是不同的进程,因此父进程C.staticDict不受影响。

如果要在进程之间共享数据,则必须按照精细手册中的说明使用Queue

相关内容

  • 没有找到相关文章

最新更新