Worker / Child实例中的函数不会返回,冻结程序

时间:2014-05-30 15:56:32

标签: python python-2.7 multiprocessing

我在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个浮点值。

欢迎任何建议!

1 个答案:

答案 0 :(得分:1)

这实际上是一种有根据的猜测而没有真正看到工人正在做什么,但是你的孩子是否有可能将物品放入尚未被消费的Queue中? documentation对此有警告:

  

警告

     

如上所述,如果子进程已将项目放入队列(和   它没有使用JoinableQueue.cancel_join_thread),然后是那个进程   直到所有缓冲的项目都被刷新为止后才会终止   管。

     

这意味着如果您尝试加入该流程,可能会陷入僵局   除非您确定所有已放入队列的项目   已被消耗。同样,如果子进程是非守护进程的   然后父进程在尝试加入所有进程时可能会在退出时挂起   非守护儿童。

     

请注意,使用管理器创建的队列没有此问题。   见Programming guidelines.

尝试使用Queue创建mp.Manager.Queue对象并查看问题是否消失可能值得。