简体   繁体   English

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

[英]end python multithreading if one of the threads end first

So, I have the following code which im using to run the tasks in multiple functions at the same time: 因此,我有以下代码可用于同时运行多个功能中的任务:

        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]

This works well for me. 这对我来说很好。 I'm currently using it to run two jobs at the same time. 我目前正在使用它同时运行两个作业。

But the problem is, i dont always need all the two simultaneously running jobs to complete before I move on to the next phases of the script. 但是问题是,在继续进行脚本的下一阶段之前,我并不总是需要同时完成两个同时运行的作业。 Sometimes, if the first job completes successfully and im able to confirm it by verifying whats in matchesBegin, matchesEnd, I want to be able to just move on and kill off the other job. 有时,如果第一个作业成功完成,并且无法通过验证matchBegin,matchesEnd中的内容来确认它,我希望能够继续前进并杀死另一个作业。

My issue is, i dont know how to do that. 我的问题是,我不知道该怎么做。

Job 1 usually completes much faster than Job 2. So, what im trying to do here is, IF job 1 completes before Job 2, AND the content of the variables from Job 1 (matchesBegin, matchesEnd) is True, then, i want Job 2 to be blown away because I dont need it anymore. 作业1通常比作业2快得多。因此,我要在这里做的是,如果作业1在作业2之前完成,并且作业1中的变量的内容(matchesBegin,matchesEnd)为True,那么我希望作业2被吹走了,因为我不再需要它了。 If i dont blow it away, it will only prolong the completion of the script. 如果我不吹牛,它只会延长脚本的完成时间。 Job 2 should only be allowed to continue to run if results of the variables from Job 1 arent True. 仅当作业1的变量结果为True时,才允许作业2继续运行。

I do not know all the details of your use case, but I would hope this provides you some direction. 我不知道用例的所有细节,但是我希望这可以为您提供一些指导。 Essentially, what you've started with apply_async() could do that job, but you would also need to use its callback argument and evaluate incoming result to see if it fulfills your criteria and take a corresponding action if it does. 本质上,您从apply_async()开始的工作就可以完成该工作,但是您还需要使用其callback参数并评估传入的结果,以查看其是否满足您的条件,并执行相应的操作。 I've hacked around your code a bit and got this: 我已经破解了您的代码,并得到了以下信息:

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

Which you could use like this: 您可以这样使用:

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

What does it do? 它有什么作用? runner is an instance of ParallelCall (note: I've used only two workers as you seem to only run two jobs) which uses final_result() function to evaluate the result whether it is a suitable candidate for valid final result. runnerParallelCall一个实例(注意:由于您似乎只运行两个作业,我仅使用了两个工作程序),该函数使用final_result()函数来评估结果是否适合作为有效最终结果的候选对象。 In this case, it's first and second item are equal. 在这种情况下,第一项和第二项相等。

We use that to start getAllTimes two times like in your example above. 如上例所示,我们使用它两次启动getAllTimes It uses apply_async() just as you did, but we now also have a callback registered through which we pass the result when it becomes available. 就像您一样,它使用apply_async() ,但是我们现在还注册了一个回调,当结果可用时,我们将通过该回调传递结果。 We also pass it through the function registered with check_done to see if we got an acceptable final result and if so (return value evaluates to True ) we just stop all the worker processes. 我们还将其传递给在check_done注册的函数,以查看是否获得了可接受的最终结果,如果是这样(返回值评估为True ),我们将停止所有工作进程。

Disclaimer: this is not exactly what your example does, because the returning list is not in order in which function calls has taken place, but in which the results became available. 免责声明:这并不完全是您的示例所做的事情,因为返回列表不是按顺序进行函数调用,而是按顺序提供结果。

Then we collect() available results into feedback . 然后我们collect()可用结果collect()feedback This method closes the pool to not accept any further tasks ( close() ) and then waits for the workers to finish ( wait() ) (they could be stopped if one of the incoming results matched the registered criterion). 此方法关闭池以不接受任何其他任务( close() ),然后等待工作人员完成( wait() )(如果传入结果之一与注册条件匹配,它们可能会停止)。 Then we return all the results (either up to matching result or until all work has been done). 然后,我们返回所有结果(直到匹配的结果或直到完成所有工作为止)。

I've put this into ParallelCall class so that I can conveniently keep track of the pending and finished results as well know what my pool is. 我将其放入ParallelCall类中,以便可以方便地跟踪挂起和完成的结果以及知道我的池是什么。 Default check_done is basically a (callable) nop . 默认的check_done基本上是(可调用的) nop

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM