我在python中使用多处理模块。以下是我正在使用的代码示例:
import multiprocessing as mp
def function(fun_var1, fun_var2):
b = fun_var1 + fun_var2
# and more computationally intensive stuff happens here
return b
# my program freezes after the return command
class Worker(mp.Process):
def __init__(self, queue_obj, func_var1, func_var2):
mp.Process.__init__(self)
self.queue_obj = queue_obj
self.func_var1 = func_var1
self.func_var2 = func_var2
def run(self):
self.var = function( self.func_var1, self.func_var2 )
self.queue_obj.put(self.var)
if __name__ == '__main__':
mp.freeze_support()
queue_list = []
processes = []
result = []
for i in range(2):
queue_list.append(mp.Queue())
processes.append( Worker(queue_list[i], i, var1, var2 )
processes[i].start()
for i in range(2):
processes[i].join()
result.append(queue_list[i].get())
在程序运行期间,生成两个同时工作的worker类实例。一个实例在大约2分钟后完成,另一个实例大约需要7分钟。第一个实例返回结果很好。但是,当run()方法中调用的function()返回其值时,第二个实例会冻结程序。没有错误被抛出,程序就不会继续执行。控制台还指示它正忙但没有显示>>>提示。我完全不知道为什么会出现这种情况。相同的代码适用于两个Worker实例中略有不同的输入。我能说出的唯一区别是工作负载在正确执行时更加平等。这个时差会造成麻烦吗?有没有人有这种行为的经验?另请注意,如果我运行程序的串行设置,其中function()刚被主程序调用两次,则代码执行完美无缺。工作者实例中是否存在一些超时,使得function()无法将其值返回到Worker实例? function()的返回值实际上是一个相当小的列表。它包含大约100个浮点值。
欢迎任何建议!
答案 0 :(得分:1)
这实际上是一种有根据的猜测而没有真正看到工人正在做什么,但是你的孩子是否有可能将物品放入尚未被消费的Queue
中? documentation对此有警告:
警告
如上所述,如果子进程已将项目放入队列(和 它没有使用JoinableQueue.cancel_join_thread),然后是那个进程 直到所有缓冲的项目都被刷新为止后才会终止 管。
这意味着如果您尝试加入该流程,可能会陷入僵局 除非您确定所有已放入队列的项目 已被消耗。同样,如果子进程是非守护进程的 然后父进程在尝试加入所有进程时可能会在退出时挂起 非守护儿童。
请注意,使用管理器创建的队列没有此问题。 见Programming guidelines.
尝试使用Queue
创建mp.Manager.Queue
对象并查看问题是否消失可能值得。