【发布时间】:2018-01-29 20:55:47
【问题描述】:
我有一个大型程序(特别是一个函数),我正在尝试使用JoinableQueue 和多处理map_async 方法进行并行化。我正在使用的函数对多维数组执行多项操作,因此我将每个数组分成多个部分,每个部分独立评估;但是我需要尽早将其中一个数组缝合在一起,但是“缝合”发生在“评估”之前,我需要在 JoinableQueue 中引入某种延迟。我已经到处寻找可行的解决方案,但我对多处理非常陌生,其中大部分都超出了我的想象。
这个措辞可能会令人困惑 - 道歉。这是我的代码大纲(我不能把它全部都放出来,因为它很长,但如果需要我可以提供更多细节)
import numpy as np
import multiprocessing as mp
from multiprocessing import Pool, Pipe, JoinableQueue
def main_function(section_number):
#define section sizes
array_this_section = array[:,start:end+1,:]
histogram_this_section = np.zeros((3, dataset_size, dataset_size))
#start and end are defined according to the size of the array
#dataset_size is to show that the histogram is a different size than the array
for m in range(1,num_iterations+1):
#do several operations- each section of the array
#corresponds to a section on the histogram
hist_queue.put(histogram_this_section)
#each process sends their own part of the histogram outside of the pool
#to be combined with every other part- later operations
#in this function must use the full histogram
hist_queue.join()
full_histogram = full_hist_queue.get()
full_hist_queue.task_done()
#do many more operations
hist_queue = JoinableQueue()
full_hist_queue = JoinableQueue()
if __name__ == '__main__':
pool = mp.Pool(num_sections)
args = np.arange(num_sections)
pool.map_async(main_function, args, chunksize=1)
#I need the map_async because the program is designed to display an output at the
#end of each iteration, and each output must be a compilation of all processes
#a few variable definitions go here
for m in range(1,num_iterations+1):
for i in range(num_sections):
temp_hist = hist_queue.get() #the code hangs here because the queue
#is attempting to get before anything
#has been put
hist_full += temp_hist
for i in range(num_sections):
hist_queue.task_done()
for i in range(num_sections):
full_hist_queue.put(hist_full) #the full histogram is sent back into
#the pool
full_hist_queue.join()
#etc etc
pool.close()
pool.join()
【问题讨论】:
-
我不确定我是否理解您的代码中发生的情况。怎么了?你有例外吗?僵局?我在您的代码中看到的唯一可能粗略的事情是,子进程是否会获得与父进程相同的
Queue对象并不明显,因为您没有将它们作为参数传递(传递给Pool中的设置函数)。如果multiprocessing正在分叉,代码可能可以工作,但如果不是,它可能不会工作,因为队列会有所不同。 -
我的代码挂在
temp_hist = hist_queue.get()行,因为主函数需要更长的时间才能进入hist_queue.put()命令,所以get()命令挂起是因为队列中没有任何内容。如果可能的话,我想以某种方式延迟.get()呼叫,直到队列中有东西为止 -
get调用不阻塞吗?看起来它应该完全按照您的意愿行事。没有死锁,因为其他进程最终会将其直方图添加到队列中。到底是什么问题? -
阻塞完全停止程序。它只是挂起。主函数不会继续评估,因此不会通过队列发送直方图。我已经用一系列打印命令对此进行了测试,以告诉我函数在哪里进行,并且在调用任何
put()命令之前它会停止。我相信这是map_async方法的产物,它允许调用下面的代码与函数参数同时执行,但我想推迟map_async下面的代码,直到主函数到达@987654335 @ 命令 -
原进程何时调用
get无关紧要,直到第一个子进程调用put,然后唤醒。使其陷入僵局的唯一方法是队列无法正常工作。是否有任何东西通过队列成功发送?
标签: python queue python-multiprocessing