当其中一个工作人员找到适当的解决方案时终止多进程池

时间:2017-07-14 10:09:54

标签: python python-3.x multiprocessing

我已经创建了一个程序,可以总结为这样的程序:

from itertools import combinations
class Test(object):
    def __init__(self, t2):
        self.another_class_object = t2

def function_1(self,n):
   a = 2
   while(a <= n):
       all_combs = combinations(range(n),a)
       for comb in all_combs:
           if(another_class_object.function_2(comb)):
              return 1
       a += 1
   return -1

combinations导入功能itertoolsFunction_2根据输入返回TrueFalse,并且是另一个类对象中的方法,例如:

class Test_2(object):

def __init__(self, list):
    self.comb_list = list

def function_2(self,c):
    return c in self.comb_list

一切都很好。但现在我想稍微改变它并实现多处理。我发现this topic显示了当一个工作进程确定不再需要完成工作时如何退出脚本的示例。所以我做了以下更改:

  1. 将游戏池的定义添加到__init__方法:self.pool = Pool(processes=8)
  2. 创建了一个回调函数:

    all_results = []
    def callback_function(self, result):
        self.all_results.append(result)
        if(result):
            self.pool.terminate()
    
  3. 更改了function_1

    def function_1(self,n):
        a = 2
        while(a <= n):
           all_combs = combinations(range(n),a)
           for comb in all_combs:
               self.pool.apply_async(self.another_class_object.function_2, args=comb, callback=self.callback_function)
           #self.pool.close()
           #self.pool.join()
           if(True in all_results):
               return 1
           a += 1
       return -1
    
  4. 不幸的是,它不像我预期的那样有效。为什么?调试后看起来似乎永远不会到达回调函数。我以为每个工人都会达成。我错了吗?可能是什么问题?

2 个答案:

答案 0 :(得分:1)

我没有尝试你的代码,但我尝试了你的结构。你确定问题出在回调函数而不是worker函数吗?如果函数是类方法,我没有设法让apply_async启动worker函数的单个实例。它没有做任何事情。 Apply_async完成且没有错误,但它没有实现worker。

只要将worker函数(在您的情况下为another_class_object.function2)作为类外的独立全局函数移动,它就会按预期开始工作并且正常触发回调。相反,回调函数似乎可以作为类方法正常工作。

这里似乎有关于此的讨论:Why can I pass an instance method to multiprocessing.Process, but not a multiprocessing.Pool?

这有用吗?

哈努哈利

答案 1 :(得分:1)

  

问题:...按照我的预期不能正常工作。 ......可能是什么问题?

始终需要get() pool.apply_async(...的结果来查看池进程中的错误。

更改为以下内容:

pp = []
for comb in all_combs:
    pp.append(pool.apply_async(func=self.another_class_object.function_2, args=comb, callback=self.callback_function))

pool.close()

for ar in pp:
    print('ar=%s' % ar.get())
  

您会看到此错误:

TypeError: function_2() takes 2 positional arguments but 3 were given

修复此错误,将args=comb更改为args=(comb,)

pp.append(pool.apply_async(func=self.another_class_object.function_2, args=(comb,), callback=self.callback_function))

使用Python测试:3.4.2