我想实现一个递归并行算法,我希望只创建一次池,每次执行一个作业等待所有作业完成,然后再次使用先前输出的输入调用进程,然后再次在下一个时间步骤等同等。
我的问题是我已经实现了一个版本,其中每次创建并杀死池的步骤,但这非常慢,甚至比顺序版本慢。当我尝试实现一个只在开始时创建池的版本时,当我尝试调用join()时出现断言错误。
这是我的代码
def log_result(result):
tempx , tempb, u = result
X[:,u,np.newaxis], b[:,u,np.newaxis] = tempx , tempb
workers = mp.Pool(processes = 4)
for t in range(p,T):
count = 0 #==========This is only master's job=============
for l in range(p):
for k in range(4):
gn[count]=train[t-l-1,k]
count+=1
G = G*v + gn @ gn.T#==================================
if __name__ == '__main__':
for i in range(4):
workers.apply_async(OULtraining, args=(train[t,i], X[:,i,np.newaxis], b[:,i,np.newaxis], i, gn), callback = log_result)
workers.join()
X和b是我想直接在主存储器中更新的矩阵。
这里有什么问题,我得到断言错误?
我可以在池中实现我想要的内容吗?
答案 0 :(得分:1)
您无法加入未先关闭的池,因为join()
将等待工作进程终止,而不是要完成的作业(https://docs.python.org/3.6/library/multiprocessing.html第17.2.2.9节)。
但是因为这将关闭池,这不是你想要的,你不能使用它。所以加入已经结束,你需要实施一个"等待所有工作完成"靠自己。
在没有繁忙循环的情况下执行此操作的一种方法是使用队列。您也可以使用有界信号量,但它们不适用于所有操作系统。
counter = 0
lock_queue = multiprocessing.Queue()
counter_lock = multiprocessing.Lock()
def log_result(result):
tempx , tempb, u = result
X[:,u,np.newaxis], b[:,u,np.newaxis] = tempx , tempb
with counter_lock:
counter += 1
if counter == 4:
counter = 0
lock_queue.put(42)
workers = mp.Pool(processes = 4)
for t in range(p,T):
count = 0 #==========This is only master's job=============
for l in range(p):
for k in range(4):
gn[count]=train[t-l-1,k]
count+=1
G = G*v + gn @ gn.T#==================================
if __name__ == '__main__':
counter = 0
for i in range(4):
workers.apply_async(OULtraining, args=(train[t,i], X[:,i,np.newaxis], b[:,i,np.newaxis], i, gn), callback = log_result)
lock_queue.get(block=True)
这会在提交作业之前重置全局计数器。作业完成后,您将回调增加全局计数器。当计数器达到4(您的工作数)时,回调知道它已经处理了最后的结果。然后在队列中发送虚拟消息。您的主程序正在Queue.get()
等待某些内容出现在那里。
这允许您的主程序在所有作业完成之前阻止,而不关闭池。
如果您使用multiprocessing.Pool
中的ProcessPoolExecutor
替换concurrent.futures
,则可以跳过此部分并使用
concurrent.futures.wait(fs, timeout=None, return_when=ALL_COMPLETED)
阻止,直到所有提交的任务都完成。从功能的角度来看,这些之间没有区别。 concurrent.futures方法的行数较短,但结果完全相同。