nit*_*tin 4 python multiprocessing
我有一个名为实验的课程和另一个名为案例的课程。一项实验是由许多个别案例组成的。请参阅下面的类定义,
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
Run Code Online (Sandbox Code Playgroud)
在我的实验类中,我有一个名为 sr_execute 的函数。该函数显示了所需的行为。我有兴趣解析所有案例并为每个案例设置一个属性。当我运行以下代码时,
if __name__ == '__main__':
#multiprocessing.freeze_support()
e = Experiment('exp')
e.sr_execute()
for c in e.cases: print c.name, c.var
Run Code Online (Sandbox Code Playgroud)
我明白了,
a 6
b 6
c 6
Run Code Online (Sandbox Code Playgroud)
这是期望的行为。
但是,我想使用多处理并行执行此操作。为此,我将 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]
Run Code Online (Sandbox Code Playgroud)
然而,这是行不通的。当我执行以下命令时,
if __name__ == '__main__':
#multiprocessing.freeze_support()
e = Experiment('exp')
e.mp_execute()
for c in e.cases: print c.name, c.var
Run Code Online (Sandbox Code Playgroud)
我收到一个错误,
AttributeError: 'Case' object has no attribute 'var'
Run Code Online (Sandbox Code Playgroud)
显然,我无法使用多处理设置类属性。
任何线索都发生了什么,
你打电话时:
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]
Run Code Online (Sandbox Code Playgroud)
当您创建它时Process,它将使用对象的副本,并且对该对象的修改不会传递到主程序,因为不同的进程具有不同的地址空间。如果您使用 s ,那么它会起作用,Thread因为在这种情况下不会创建副本。
另请注意,您的代码在 Windows 中可能会失败,因为您正在传递一个方法,target而 Windows 要求该方法target可挑选(并且实例方法不可挑选)。它target应该是在模块顶层定义的函数,以便在所有操作系统上工作。
如果您想向主进程传达更改,您可以:
无论如何,您必须Queue通过设置“通道”(如)或设置共享状态来“显式”处理通信。
风格注释:不要以这种方式使用列表推导式:
[p.join() for p in processes]
Run Code Online (Sandbox Code Playgroud)
这根本就是错误的。您只是在浪费空间来创建 s 列表None。与正确的方法相比,它也可能更慢:
for p in processes:
p.join()
Run Code Online (Sandbox Code Playgroud)
因为它必须将元素附加到列表中。
然而,有人说列表推导式比for循环稍快:
当且仅当您考虑这种循环时它们才会更快:
a = []
for element in something:
a.append(element)
Run Code Online (Sandbox Code Playgroud)
如果循环(如本例所示)不创建,list则for循环会更快。
顺便说一句:有些以map同样的方式使用会产生副作用。这又是错误的,因为与以前相同的原因,你不会获得太多的速度,并且它在map返回迭代器的 python3 中完全失败,因此它根本不会执行函数,从而使代码的可移植性较差。
| 归档时间: |
|
| 查看次数: |
6124 次 |
| 最近记录: |