zoukankan      html  css  js  c++  java
  • python函数超时情况应对总结

    最近处理一个线程中的函数超时问题.

    函数里面有一个地方可能会卡死,我们需要去判断这个是不是卡死了,并做出相应的应对方案.

    最开始想的是在函数上增加一个装饰器,使其在超时时抛出异常,然后在其他地方捕获这个异常,并处理.

    查询了一些前人的方案,写出的结果有两种.

    方案一:使用threading的timer定时器,代码如下:

    from threading import timer

    def
    time_limit(interval): def wraps(func): def time_out(): raise RuntimeError() def deco(*args, **kwargs): timer = Timer(interval, time_out) timer.start() res = func(*args, **kwargs) timer.cancel() return res return deco return wraps

    这个程序,在很多网页上看到了,使用方式,在需要监控的函数上写@time_limit(5),即可定时5秒报错.经过测试,觉得没什么用.

    粗略看来,运行一下确实在程序超过interval规定的时间后抛出了RuntimeError.但是由于timer是另开的一个线程,所以这个异常别人获取不到,只有在本线程里处理才有用.

    而且卡死的函数也不会停下来.

    这种处理方式仅仅适用于一些函数与定时并不密切的时候,只是在函数超时时需要做一些动作的情况.

    方案二:使用signal信号量机制,代码如下:

    
    
    import signal
    def time_limit(interval):
        def wraps(func):
            def handler():
                raise RuntimeError()
            def deco(*args, **kwargs):
                signal.signal(signal.SIGALRM, handler)
                signal.alarm(interval)
                res = func(*args, **kwargs)
                signal.alarm(0)
                return res
            return deco
        return wraps

    可以看出来,代码基本一样.但是原理大不相同.运行的结果也不一样,这段代码装饰需要定时的函数,在函数运行超时之后会抛出异常,停止程序.

    一般情况下,这个装饰器就够用了.与之相同的方案,还有python的timeout模块,

    可以直接pip install timeout,然后from timeout import timeout,在需要的函数前@timeout(n)即可.

    这个方案已经很不错了,然而在实际应用中,由于是多线程,而signal不能在子线程中使用,所以否认了这个方案.

    比较简单的装饰器想法否定掉了,就想了一些其他的办法.

    1.定时检测线程是否alive----------卡死的线程只是不动,还是alive的

    2.由于函数是生产者,可以通过计算时间,一定时间没有新的产出,则判定这个函数卡死,然后杀掉这个线程,重开一个----------python不支持杀掉线程

    3.在线程里面增加标志位,检测标志位改变则退出循环----------天真的想法

    4.改变线程为可接受stop的线程----------卡住不动收不到信号的,除非是进程

    提出一些方案发现可行性都很低,最后也没有完全解决卡死的问题.

    虽然这一个线程卡死并不会影响整个程序往下走,但是不生产,又占据资源不合理.

    觉得否认了这些方案以后,最干脆的办法是检测到这个卡死之后,手动或自动杀掉其父进程.重启服务.

    还有较不优雅的办法,由于卡死的情况不会很多,就记录下来,然后新开一个线程替代它的工作,直到记录队列满了,给一个信号要求重启服务.

    重启服务影响较大,不建议随便重启.

    总的说下来,还是没有较好的方案解决线程卡死的问题,毕竟函数卡死了就是卡死了,没法走下去,而且在线程里面又没法外界停下来.

    先做一个记录吧!在继续学习的路上,希望有好的办法.

  • 相关阅读:
    好玩的贪吃蛇小游戏,有趣极了!
    vue的多选框存储值操作
    vue和jquery嵌套实现异步ajax通信
    vue的组件学习———做一个简易机器人
    vue监听属性完成首字母大小写转换
    Vue多选框的绑定
    Vue.js的简介、属性
    MySQL数据库(5)
    DRF的json web token方式完成用户认证
    DRF跨域问题
  • 原文地址:https://www.cnblogs.com/masako/p/6807166.html
Copyright © 2011-2022 走看看