如果其中一个线程先结束,则结束python多线程

时间:2018-07-16 21:19:34

标签: python

因此,我有以下代码可用于同时运行多个功能中的任务:

        if __name__ == '__main__':
            po = Pool(processes = 10)
            resultslist = []
            i = 1
            while i <= 2:
                arg = [i]
                result = po.apply_async(getAllTimes, arg)
                resultslist.append(result)
                i += 1

            feedback = []
            for res in resultslist:
                multipresults = res.get()
                feedback.append(multipresults)

matchesBegin, matchesEnd = feedback[0][0], feedback[0][1]
TheTimes = feedback[1]

这对我来说很好。我目前正在使用它同时运行两个作业。

但是问题是,在继续进行脚本的下一阶段之前,我并不总是需要同时完成两个同时运行的作业。有时,如果第一个作业成功完成,并且无法通过验证matchBegin,matchesEnd中的内容来确认它,那么我希望能够继续前进并杀死另一个作业。

我的问题是,我不知道该怎么做。

作业1的完成速度通常比作业2快得多。因此,我要做的是,如果作业1在作业2之前完成,并且来自作业1的变量(matchesBegin,matchesEnd)的内容为True,那么,我希望工作2被吹走,因为我不再需要它。如果我不吹牛,它只会延长脚本的完成时间。仅当作业1的变量结果为True时,才允许作业2继续运行。

1 个答案:

答案 0 :(得分:2)

我不知道用例的所有细节,但是我希望这可以为您提供一些指导。本质上,您从apply_async()开始的工作就可以完成这项工作,但是您还需要使用其callback参数并评估传入的结果以查看其是否满足您的条件,并采取相应的措施做。我已经破解了您的代码,并得到了这个:

class ParallelCall:
    def __init__(self, jobs=None, check_done=lambda res: None):
        self.pool = Pool(processes=jobs)
        self.pending_results = []
        self.return_results = []
        self.check_done = check_done

    def _callback(self, incoming_result):
        self.return_results.append(incoming_result)
        if self.check_done(incoming_result):
            self.pool.terminate()
        return incoming_result

    def run_fce(self, fce, *args, **kwargs):
        self.pending_results.append(self.pool.apply_async(fce,
                                                          *args, **kwargs,
                                                          callback=self._callback))

    def collect(self):
        self.pool.close()
        self.pool.join()
        return self.return_results

您可以这样使用:

def final_result(result_to_check):
    return result_to_check[0] == result_to_check[1]

if __name__ == '__main__':
    runner = ParallelCall(jobs=2, check_done=final_result)
    for i in range(1,3):
        arg = [i]
        runner.run_fce(getAllTimes, arg)

    feedback = runner.collect()

    TheTimes = feedback[-1]  # last completed getAllTimes call

它有什么作用? runnerParallelCall的一个实例(注意:由于您似乎只运行两个作业,我只使用了两个工作程序),它使用final_result()函数来评估结果是否合适有效最终结果的候选者。在这种情况下,它的第一项和第二项是相等的。

与上面的示例一样,我们使用它两次启动getAllTimes。就像您一样,它使用apply_async(),但现在我们也注册了一个回调,当结果可用时,我们将通过该回调传递结果。我们还将其通过在check_done中注册的函数进行传递,以查看是否获得可接受的最终结果,如果可以,(返回值评估为True),我们将停止所有工作进程。

免责声明:这与您的示例不完全一样,因为返回列表并不按顺序进行函数调用,而是按顺序提供结果。

然后我们将collect()的可用结果放入feedback中。此方法关闭池以不接受任何其他任务(close()),然后等待工作程序完成(wait())(如果传入结果之一与注册标准匹配,它们可能会停止)。然后,我们返回所有结果(直到匹配的结果,或者直到完成所有工作为止)。

我将其放入ParallelCall类中,以便可以方便地跟踪待处理和完成的结果,以及知道我的池是什么。默认的check_done基本上是(可调用的)nop