正如其他人所说,解决方案是使用多个流程。然而,哪种框架更合适取决于许多因素。除了已经提到的那些,还有charm4py和mpi4py(我是charm4py的开发者)。
与使用工作池抽象相比,实现上述示例的方法更有效。主循环G在1000次迭代的每次迭代中反复向工人发送相同的参数(包括完整的图形)。由于至少有一个worker将驻留在不同的进程上,这涉及复制并将参数发送给其他进程。根据物体的大小,这可能非常昂贵。相反,让工人存储状态并简单地发送更新的信息是有意义的。
例如,在charm4py中可以这样做:class Worker(Chare):
def __init__(self, Q, G, n):
self.G = G ...
def setinner(self, node1, node2):
self.updateGraph(node1, node2)
...def solve(Q, G, n):
# create 2 workers, each on a different process, passing the initial state
worker_a = Chare(Worker, onPE=0, args=[Q, G, n])
worker_b = Chare(Worker, onPE=1, args=[Q, G, n])
while i < 1000:
result_a = worker_a.setinner(node1, node2, ret=True) # execute setinner on worker A
result_b = worker_b.setouter(node1, node2, ret=True) # execute setouter on worker B
inneropt, partition, x = result_a.get() # wait for result from worker A
outeropt = result_b.get() # wait for result from worker B
...
请注意,对于此示例,我们实际上只需要一个工作者。主循环可以执行其中一个函数,让工作者执行另一个函数。但是我的代码有助于说明一些事情:工作者A在进程0中运行(与主循环相同)。当result_a.get()被阻塞等待结果时,工作人员A在同一过程中进行计算。
参数自动通过引用传递给工作者A,因为它在同一个进程中(不涉及复制)。