python防止程序超时研究

因为某个需求,需要在程序运行的时候防止超时。在网上搜了以下发现有3种方法
1.@func_set_timeout这个注解
实测可以用,但是用起来比较麻烦,因为这个超时后会跑出异常,可以直接注解在函数上但不能注解在单条语句上,我设想的是把超时和异常同时处理,这个会抛出新的异常不太符合我的需求

# func_set_timeout作为装饰器使用,来作为目标函数的超时处理方式
import time
import os
from func_timeout import func_set_timeout


@func_set_timeout(5)
def my_test(name):
    print('子进程运行中,name={},pid={}'.format(name, os.getpid()))
    time.sleep(4)			
    print('子进程已经结束')


if __name__ == '__main__':
    print('父进程:{}'.format(os.getpid()))
    try:
        p = Process(target=my_test, args=('test', ))
        p.start()
    except TimeoutError as e:
        print('子程序超时')

2.多进程/多限制的.join
比如下面的代码

import time
import threading

def worker():
    print('worker start')
    time.sleep(10)
    print('worker end')

t = threading.Thread(target=worker)
t.start()

# 等待线程结束,不能超过5秒
t.join(5)

if t.is_alive():
    print('worker overtime')
else:
    print('worker finished')

实测发现运行结果是这样,到了5秒提示overtime但是程序继续运行,然后到了10秒程序运行结束,虽然有超时的效果但是和我设想的还是有区别,我想的是时间到了你就别继续运行了

3.使用eventlet.Timeout来实现,实测下来这个是最符合我需求的,时间到了直接跳出,加一个timeout的变量就能知道是否超时了。美中不足就是必须加一条语句,eventlet.monkey_patch(),简单搜索了下发现这个属于程序在运行时动态对已有代码进行修改,而不需要修改原始代码的一个热补丁。
使用了eventlet后,同时处理超时和异常的代码如下

"""
用于处理函数超时的情况,同时记录程序异常
"""
import eventlet


class PyTimer:
    """
    用于在处理异常的同时防止程序超时
    """

    def __init__(self, max_time=5):
        """
        初始化
        """
        # 必须有这条代码
        eventlet.monkey_patch()
        self.errors = ""
        # 最大超时的秒数
        self.max_time = max_time

    def set_max_time(self,new_time):
        """
        设置新的超时秒数
        """
        self.max_time=new_time

    def count_time(self, function, *args):
        """
        运行函数,记录异常,同时超时跳出
        """
        return_result = None
        timeout = True
        current_error = ""
        try:
            with eventlet.Timeout(self.max_time, False):  # 设置超时时间为5秒
                return_result = function(*args)
                timeout = False
        except Exception as e:
            current_error = str(e) + "\n"
        finally:
            if timeout:
                current_error += function.__name__ + "超时\n"
                print(current_error)
                self.errors += current_error
            return return_result

    def get_errors(self):
        """
        获取报错信息
        """
        return self.errors


if __name__ == '__main__':
    def long_fun(a, b):
        import time
        print(a, b)
        time.sleep(20)


    my_timer = PyTimer()
    my_timer.count_time(long_fun, 1, 2)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值