問題描述
有沒有一種簡單的方法可以使用多處理來完成此操作?
Is there a simple way to use Multiprocessing to do the equivalent of this?
for sim in sim_list:
sim.run()
其中 sim_list 的元素是模擬"對象,而 run() 是模擬類的一個方法,它確實修改對象的屬性.例如:
where the elements of sim_list are "simulation" objects and run() is a method of the simulation class which does modify the attributes of the objects. E.g.:
class simulation:
def __init__(self):
self.state['done']=False
self.cmd="program"
def run(self):
subprocess.call(self.cmd)
self.state['done']=True
sim_list 中的所有 sim 都是獨立的,因此策略不必是線程安全的.
All the sim in sim_list are independent, so the strategy does not have to be thread safe.
我嘗試了以下,這顯然是有缺陷的,因為參數是通過 deepcopy 傳遞的,并且沒有就地修改.
I tried the following, which is obviously flawed because the argument is passed by deepcopy and is not modified in-place.
from multiprocessing import Process
for sim in sim_list:
b = Process(target=simulation.run, args=[sim])
b.start()
b.join()
推薦答案
做你想做的事情的一種方法是讓你的計算類(simulation
在你的例子中)成為 的子類處理
.正確初始化后,此類的實例將在單獨的進程中運行,您可以根據需要從列表中設置一組實例.
One way to do what you want is to have your computing class (simulation
in your case) be a subclass of Process
. When initialized properly, instances of this class will run in separate processes and you can set off a group of them from a list just like you wanted.
這是一個示例,基于您上面寫的內容:
Here's an example, building on what you wrote above:
import multiprocessing
import os
import random
class simulation(multiprocessing.Process):
def __init__(self, name):
# must call this before anything else
multiprocessing.Process.__init__(self)
# then any other initialization
self.name = name
self.number = 0.0
sys.stdout.write('[%s] created: %f
' % (self.name, self.number))
def run(self):
sys.stdout.write('[%s] running ... process id: %s
'
% (self.name, os.getpid()))
self.number = random.uniform(0.0, 10.0)
sys.stdout.write('[%s] completed: %f
' % (self.name, self.number))
然后只需制作一個對象列表并以循環開始每個對象:
Then just make a list of objects and start each one with a loop:
sim_list = []
sim_list.append(simulation('foo'))
sim_list.append(simulation('bar'))
for sim in sim_list:
sim.start()
當您運行它時,您應該會看到每個對象都在其自己的進程中運行.不要忘記調用 Process.__init__(self)
作為類初始化中的第一件事,然后再進行其他操作.
When you run this you should see each object run in its own process. Don't forget to call Process.__init__(self)
as the very first thing in your class initialization, before anything else.
顯然我沒有在這個例子中包含任何進程間通信;如果您的情況需要,您必須添加它(從您的問題中不清楚您是否需要它).
Obviously I've not included any interprocess communication in this example; you'll have to add that if your situation requires it (it wasn't clear from your question whether you needed it or not).
這種方法對我很有效,我不知道有什么缺點.如果有人知道我忽略的隱患,請告訴我.
This approach works well for me, and I'm not aware of any drawbacks. If anyone knows of hidden dangers which I've overlooked, please let me know.
我希望這會有所幫助.
這篇關于Python Multiprocessing - 將類方法應用于對象列表的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!