【问题标题】:How to terminate a single async task in multiprocessing if that single async task exceeds a threshold time in Python如果单个异步任务超过 Python 中的阈值时间,如何在多处理中终止单个异步任务
【发布时间】:2015-12-18 15:32:43
【问题描述】:

如果单个异步任务超过 Python 中的阈值时间(例如 60 秒),如何在 WINDOWS 中使用多处理终止单个异步任务?

import multiprocessing as mp  

def compute(test_num):  
    return test_num ** 2

def main():  

    test_num_list = [10, 20, 30, 40, 50, 60, 70, 80]

    pool = mp.Pool(processes=3)  
    results = [pool.apply_async(compute, args=(test_num,)) for test_num in test_num_list]

    output = [r.get() for r in results]  
    print output 

【问题讨论】:

  • 它显示什么错误?我只是尝试运行它,它对我有用
  • @DorElias 我已经更正了我的问题。请问可以给我答案吗?

标签: python multiprocessing


【解决方案1】:

据我所知,没有办法杀死已经发送到 Pool 对象的任务。

由于您控制子进程,您可以创建自己的“看门狗”计时器,以确保该进程的执行时间不会超过某个设定的时间。一种方法是生成一个线程,该线程在超时条件事件上等待,如果计算没有及时完成,则终止进程:

from threading import Thread, Event
import multiprocessing as mp
import sys

def watchdog(e):
    finished = e.wait(timeout=60)  # returns True if Event signaled
    if not finished:
        sys.exit(-1)

def compute(test_num):
    return test_num ** 2

def time_limited_compute(test_num):  # Use this as the target of your process
    e = Event()
    Thread(target=watchdog, args=(e,)).start()

    r = compute(test_num)

    e.set()
    return r

因为 multiprocessing.Pool 将重新生成任何在执行任务时死亡的进程,这应该会给你你正在寻找的结果。

确保你也为你的 get() 调用设置了一个超时时间。因为这会在它超时的情况下抛出一个multiprocessing.TimeoutError,所以你需要处理它:

def main():

    test_num_list = [10, 20, 30, 40, 50, 60, 70, 80]

    pool = mp.Pool(processes=3)
    results = [pool.apply_async(time_limited_compute, args=(test_num,)) 
               for test_num in test_num_list]

    def get_or_none(r):
        try: return r.get(60)
        except mp.TimeoutError: 
            return None

    output = [get_or_none(r) for r in results]
    print output

if __name__ == '__main__':
    main()

【讨论】:

  • 谢谢@MykWills。代码在超时时显示以下错误(进程也不会终止):文件“C:\Users\darwin\Desktop\FCT_v2.31\FCT_2.35_timeout.py”,第 2989 行,在 Execute_Projects 输出 = [r. get(timeout=60) for r in results] 文件“C:\Python27\lib\multiprocessing\pool.py”,第 563 行,在 get raise TimeoutError TimeoutError 中。你能告诉我为什么会这样吗?非常感谢您的回答!
  • @zaman 我修复了代码以捕获在超时情况下将被抛出的multiprocessing.TimeoutError get。刚刚在我的本地盒子上测试了这个,它似乎可以解决问题。
【解决方案2】:

已经回答了here您的问题。

您可以为此目的使用pebble 进程池。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 2020-07-08
    • 1970-01-01
    相关资源
    最近更新 更多