python如何控制运行时间_Python控制函数运行时间

在某个Flask项目在做后端接口时需要设置超时响应,因为接口中使用爬虫请求了多个网站,响应时间时长时短。

我需要设置一个最大响应时间,时间内如果接口爬虫没跑完,直接返回请求超时。

从网上了解到有两种方法,废话不多说直接上代码。

方法1:使用线程控制

importrequests, datetime, timeimportthreadingclassMyThread(threading.Thread):def __init__(self, target, args=()):"""why: 因为threading类没有返回值,因此在此处重新定义MyThread类,使线程拥有返回值

此方法来源 https://www.cnblogs.com/hujq1029/p/7219163.html?utm_source=itdadao&utm_medium=referral"""super(MyThread, self).__init__()

self.func=target

self.args=argsdefrun(self):#接受返回值

self.result = self.func(*self.args)defget_result(self):#线程不结束,返回值为None

try:returnself.resultexceptException:returnNone#为了限制真实请求时间或函数执行时间的装饰器

deflimit_decor(limit_time):""":param limit_time: 设置最大允许执行时长,单位:秒

:return: 未超时返回被装饰函数返回值,超时则返回 None"""

deffunctions(func):#执行操作

def run(*params):

thre_func= MyThread(target=func, args=params)#主线程结束(超出时长),则线程方法结束

thre_func.setDaemon(True)

thre_func.start()#计算分段沉睡次数

sleep_num = int(limit_time // 1)

sleep_nums= round(limit_time % 1, 1)#多次短暂沉睡并尝试获取返回值

for i inrange(sleep_num):

time.sleep(1)

infor=thre_func.get_result()ifinfor:returninfor

time.sleep(sleep_nums)#最终返回值(不论线程是否已结束)

ifthre_func.get_result():returnthre_func.get_result()else:return"请求超时" #超时返回 可以自定义

returnrunreturnfunctions#接口函数

defa1():print("开始请求接口")#这里把逻辑封装成一个函数,使用线程调用

a_theadiing = MyThread(target=a2)

a_theadiing.start()

a_theadiing.join()#返回结果

a =a_theadiing.get_result()print("请求完成")returna

@limit_decor(3) #超时设置为3s 2s逻辑未执行完毕返回接口超时

defa2():print("开始执行")

time.sleep(2)print("执行完成")

a=2

returna#程序入口 未超时返回a的值 超时返回请求超时

if __name__ == '__main__':

a= a1() #调用接口(这里把函数a1看做一个接口)

print(a)

超时设置3s,线程调用函数运行2s,这里返回a的值2。

方法2:使用信号模块signal(只能在unix系统使用)

signal负责在Python程序内部处理信号,典型的操作包括预设信号处理函数,暂停并等待信号,以及定时发出SIGALRM等。

要注意,signal包主要是针对UNIX平台(比如Linux, MAC OS),而Windows内核中由于对信号机制的支持不充分,所以在Windows上的Python不能发挥信号系统的功能。

信号是进程之间通讯的方式,是一种软件中断。一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号。

defset_timeout(num):defwrap(func):def handle(signum, frame): #收到信号 SIGALRM 后的回调函数,第一个参数是信号的数字,第二个参数是the interrupted stack frame.

raiseRuntimeErrordef to_do(*args):try:

signal.signal(signal.SIGALRM, handle)#设置信号和回调函数

signal.alarm(num) #设置 num 秒的闹钟

print('start alarm signal.')

r= func(*args)print('close alarm signal.')

signal.alarm(0)#关闭闹钟

returnrexceptRuntimeError as e:return "超时啦"

returnto_doreturnwrap

@set_timeout(2) #限时 2 秒超时

def connect(): #要执行的函数

time.sleep(3) #函数执行时间,写大于2的值,可测试超时

return "完成"

if __name__ == '__main__':

a=connect()

你可能感兴趣的:(python如何控制运行时间)