美文网首页
python 超时任务kill

python 超时任务kill

作者: YG_9013 | 来源:发表于2018-05-08 15:27 被阅读0次

    编程过程中遇到代码执行超时问题。场景是在主进程中启动多个子进程并行执行,假设平时一个进程10分钟能执行完毕,但在一些极端情况下执行一个小时也没结束,此时需要杀掉子进程,返回任务执行失败。
    用python的进程池执行操作时没法设置超时时间,只能从进程内部想办法。

    思路一:

    用timer定时,当执行时间超时时让进程终止:

    def cancel_cur_computer():
        #通过抛出异常,来终止当前执行节点
        logging.warning("%s timeout killed" % str(os.getpid()))
        os.kill(os.getpid(), signal.SIGKILL)
        logging.warning("%s timeout killed" % str(os.getpid()))
    
    def run():
        timer = threading.Timer(3, cancel_cur_computer) 
        print("bbb")
        timer.start()
        time.sleep(20)
    
    def test_timer():
        pool = Pool(3)
        try:
            for i in range(0, 3):
                #run()
                pool.apply_async(run)
        except Exception as e:
            logging.exception(e)
    
        pool.close()
        pool.join()
    
    test_timer()
    

    当不用进程池时,即打开run(),注释pool.apply_async(run),执行没有问题,定时器可以杀死进程。
    当使用进程池,即注释run(),打开pool.apply_async(run),可以打印出logging.warning("%s timeout killed" % str(os.getpid())),但进程没有被杀死,反而一直卡死在os.kill(os.getpid(), signal.SIGKILL)处,我猜可能与进程池有关系。杀掉进程池中的进程也不合理。

    思路二

    用single的闹钟来解决这个问题

    def handler(signum, frame):
        raise Exception("timeout...")
    
    def run():
        try:  
            signal.signal(signal.SIGALRM, handler)  
            signal.alarm(3)   # 设置超时时间为3s
            time.sleep(40) # 模拟长时间执行任务
        except Exception as e:  
            logging.exception(e)
        finally:  
            signal.alarm(0)  # 取消闹钟
        print("aaaaa")
    
    def test_timer():
        pool = Pool(3)
        try:
            for i in range(0, 3):
                pool.apply_async(run)
        except Exception as e:
            logging.exception(e)
    
        pool.close()
        pool.join()
    
    test_timer()
    

    解决问题。

    相关文章

      网友评论

          本文标题:python 超时任务kill

          本文链接:https://www.haomeiwen.com/subject/wtfwrftx.html