我有一个叫做实验的类,另一个叫案例。一个实验是由许多个案组成的。请参阅下面的类定义,
from multiprocessing import Process
class Experiment (object):
def __init__(self, name):
self.name = name
self.cases = []
self.cases.append(Case('a'))
self.cases.append(Case('b'))
self.cases.append(Case('c'))
def sr_execute(self):
for c in self.cases:
c.setVars(6)
class Case(object):
def __init__(self, name):
self.name = name
def setVars(self, var):
self.var = var
在实验类中,我有一个名为sr_execute的函数。此功能显示所需的行为。我对解析所有案例并为每个案例设置一个属性感兴趣。当我运行以下代码时,
if __name__ == '__main__':
#multiprocessing.freeze_support()
e = Experiment('exp')
e.sr_execute()
for c in e.cases: print c.name, c.var
我明白了
a 6
b 6
c 6
这是所需的行为。
但是,我想使用多处理并行执行此操作。为此,我将mp_execute()函数添加到“实验类”中,
def mp_execute(self):
processes = []
for c in self.cases:
processes.append(Process(target= c.setVars, args = (6,)))
[p.start() for p in processes]
[p.join() for p in processes]
但是,这不起作用。当我执行以下命令时,
if __name__ == '__main__':
#multiprocessing.freeze_support()
e = Experiment('exp')
e.mp_execute()
for c in e.cases: print c.name, c.var
我得到一个错误
AttributeError: 'Case' object has no attribute 'var'
显然,我无法使用多重处理设置类属性。
任何线索,这是怎么回事,
@Bakuriu的答案提供了不错的样式和效率建议。的确,每个进程都会获得主进程堆栈的副本,因此,除非您使用某种形式的IPC(例如,队列,管道,管理器),否则分叉进程所做的更改将不会反映在主进程的地址空间中。
但具体的AttributeError: 'Case' object has no attribute 'var'
错误,你得到了一个额外的理由,即您的案例对象不还具备var
在您启动过程中的时间属性。而是var
在setVars()
方法中创建属性。
您的分叉进程确实在调用时确实创建了变量setVars()
(实际上甚至将其设置为6),但是,此更改仅在Case对象的副本中,即未反映在主进程的内存空间中(变量仍在其中不存在)。
要了解我的意思,请将您的Case类更改为:
class Case(object):
def __init__(self, name):
self.name = name
self.var = 7 # Create var in the constructor.
def setVars(self, var):
self.var = var
通过var
在构造函数中添加成员变量,您的主进程将可以访问它。当然,派生流程中的更改仍不会反映在主流程中,但至少您不会收到错误:
a 7
b 7
c 7
希望这能说明正在发生的事情。=)
解:
要做的最不麻烦的事情(对原始代码而言)是使用共享内存中的ctypes对象:
from multiprocessing import Value
class Case(object):
def __init__(self, name):
self.name = name
self.var = Value('i', 7) # Use ctypes "int" from shared memory.
def setVars(self, var):
self.var.value = var # Set the variable's "value" attribute.
并更改您的main()以打印c.var.value:
for c in e.cases: print c.name, c.var.value # Print the "value" attribute.
现在您具有所需的输出:
a 6
b 6
c 6
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句