优雅终止工人池

时间:2015-12-28 00:40:16

标签: python multithreading exit flags pool

我想生成X个池工作者并给他们每个人做X%的工作。我的问题是工作需要大约20分钟才能耗尽,每运行一次额外的过程会花费更长的时间,因为计算的类型可以在几分钟或几小时内找到我的答案。我想要做的是为一个单独的工作人员实现某种方式“我发现它”并使用该信号杀死池的其余部分并继续我的计算。

关键点:

  • 我尝试过回调,在整个游戏池完成之前,它们似乎不会在starmap_async上运行。
  • 我只关心找到的第一个合适的答案。
  • 我不是在分享资源和惊喜过程死亡,尽管很粗鲁,但是完全可以接受。

我还考虑过使用Queue,但是因为我传递给每个人的工作范围已经内置到函数的参数中,所以不会这样做。

下面是我正在使用的一个非常迟钝的版本(我正在使用的计算可能需要数小时才能完成超过42亿复杂的迭代。)

def doWork():
    workers = Pool(2)
    results = workers.starmap_async( func = distSearch , iterable = Sections1_5,  callback = killPool )
    workers.close()
    print("Found answer : {}".format(results.get()))
    workers.join()

def killPool():
    workers.terminate()
    print("Worker Pool Terminated")

我应该指定我的进程只有在找到答案时才返回,否则它只在完成后退出。我已经查看了this线程,但它完全丢失了,并且在工作池的返回/回调中应该检查win条件时似乎需要很多开销。

我发现的所有答案都会通过监督工作池来产生巨大的开销,我正在寻找一种解决方案,可以自动地在工作级别获取kill信号。

1 个答案:

答案 0 :(得分:1)

  

我正在寻找一种解决方案,可以自主地在工人级别获取杀伤信号。

AFAIK,并不存在。 Pool对象的方法(如Pool.terminate)应在创建池的过程中使用。

您可以使用Pool.imap_unordered。这会在结果中返回父进程中的迭代器,一旦结果可用就会生成结果。一旦弹出所需的结果,您就可以使用Pool.terminate()

修改

  • 从3.5实现starmap_async开始,返回MapResult实例,不是迭代器。
  • 您可以在元组中包含多个输入,并在其列表中使用imap_unordered