Python控制函数运行时间
在某个Flask项目在做后端接口时需要设置超时响应,因为接口中使用爬虫请求了多个网站,响应时间时长时短。
我需要设置一个最大响应时间,时间内如果接口爬虫没跑完,直接返回请求超时。
从网上了解到有两种方法,废话不多说直接上代码。
方法1:使用线程控制
import requests, datetime, time import threading class MyThread(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 = args def run(self): # 接受返回值 self.result = self.func(*self.args) def get_result(self): # 线程不结束,返回值为None try: return self.result except Exception: return None # 为了限制真实请求时间或函数执行时间的装饰器 def limit_decor(limit_time): """ :param limit_time: 设置最大允许执行时长,单位:秒 :return: 未超时返回被装饰函数返回值,超时则返回 None """ def functions(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 in range(sleep_num): time.sleep(1) infor = thre_func.get_result() if infor: return infor time.sleep(sleep_nums) # 最终返回值(不论线程是否已结束) if thre_func.get_result(): return thre_func.get_result() else: return"请求超时" #超时返回 可以自定义 return run return functions #接口函数 def a1(): print("开始请求接口") #这里把逻辑封装成一个函数,使用线程调用 a_theadiing = MyThread(target=a2) a_theadiing.start() a_theadiing.join() #返回结果 a = a_theadiing.get_result() print("请求完成") return a @limit_decor(3) #超时设置为3s 2s逻辑未执行完毕返回接口超时 def a2(): print("开始执行") time.sleep(2) print("执行完成") a=2 return a # 程序入口 未超时返回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不能发挥信号系统的功能。
信号是进程之间通讯的方式,是一种软件中断。一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号。
def set_timeout(num): def wrap(func): def handle(signum, frame): # 收到信号 SIGALRM 后的回调函数,第一个参数是信号的数字,第二个参数是the interrupted stack frame. raise RuntimeError def 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) # 关闭闹钟 return r except RuntimeError as e: return "超时啦" return to_do return wrap @set_timeout(2) # 限时 2 秒超时 def connect(): # 要执行的函数 time.sleep(3) # 函数执行时间,写大于2的值,可测试超时 return "完成" if __name__ == '__main__': a = connect()
简单几步手工扩容LVM、缩小LVM及移除磁盘(笔记)
python加入进度条:tqdm 和 progressbar
python的map和reduce函数
python的lambda表达式
python的推导式 —— 列表推导式、集合和字典推导式
Pyspark中遇到的 java.io.IOException: Not a file 和 pyspark.sql.utils.AnalysisException: 'Table or view not found
pyecharts绘制map地图
pyecharts绘制geo地图
sklearn.feature_extraction.text 的TfidfVectorizer函数
- 最新文章
-
kali渗透综合靶机(三)--bulldog2靶机
kali渗透综合靶机(四)--node1靶机
DVWA-基于布尔值的盲注与基于时间的盲注学习笔记
kali渗透综合靶机(二)--bulldog靶机
DVWA-SQL注入
DVWA-CSRF学习笔记
kali渗透综合靶机(一)--Lazysysadmin靶机
Linux 编写安全巡检脚本
【HCIA Gauss】学习汇总-数据库基础介绍-1
【Flask】 python学习第一章
- 热门文章
-
【Flask】 python学习第一章
【kernel】Centos 云上升级内核失败 如何处理【笔记记录转】
【ansible】密钥免密登陆使用重点
【华为云】MRS journey node HDFS 不一致
【VNCserver】Centos7.4安装VNC连接华为云或亚马逊云
openwrt多wan限上下行速脚本,基于qosv4,imq模块替换成ifb模块[ZT]
openwrt手动wifi设成client模式[笔记]
关于新版OPENWRT拔PPTP的619错或PPTPD无法连接问题笔记
openwrt中防暴力破解shell的脚本
关于openwrt使用web升级提示固件版本不对的处理方法