在某个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()

Python控制函数运行时间的更多相关文章

  1. 分析python程序运行时间的几种方法

    最早见过手写的,类似于下面这种: 1 import datetime 2 3 def time_1(): 4 begin = datetime.datetime.now() 5 sum = 0 6 f ...

  2. Python计算程序运行时间

    方法1 import datetime starttime = datetime.datetime.now() #long running endtime = datetime.datetime.no ...

  3. 计算Python代码运行时间长度方法

    在代码中有时要计算某部分代码运行时间,便于分析. import time start = time.clock() run_function() end = time.clock() print st ...

  4. Python测试函数运行时间

    import time import datetime # 测试函数运行时间 def cal_time(fn): """计算性能的修饰器""" ...

  5. Python 计算程序运行时间

    import time def start_sleep():    time.sleep(3) if __name__ == '__main__':    #The start time     st ...

  6. 计算python脚本的运行时间

    首先说一下我遇到的坑,生产上遇到的问题,我调度Python脚本执行并监控这个进程,python脚本运行时间远远大于python脚本中自己统计的程序执行时间. 监控python脚本执行的时间是36个小时 ...

  7. python测量函数运行时间长度

    python测试函数运行时间长度的方法如下 import time def measure_time(): def wraps(func): def mesure(*args,**kwargs): s ...

  8. Python丨Python 性能分析大全

    虽然运行速度慢是 Python 与生俱来的特点,大多数时候我们用 Python 就意味着放弃对性能的追求.但是,就算是用纯 Python 完成同一个任务,老手写出来的代码可能会比菜鸟写的代码块几倍,甚 ...

  9. python学习笔记之二

    1.python计算运行时间 方法1 import datetime starttime = datetime.datetime.now() #long running endtime = datet ...

随机推荐

  1. 工作中遇到的99%SQL优化,这里都能给你解决方案

    前几篇文章介绍了mysql的底层数据结构和mysql优化的神器explain.后台有些朋友说小强只介绍概念,平时使用还是一脸懵,强烈要求小强来一篇实战sql优化,经过周末两天的整理和总结,sql优化实 ...

  2. Spring中老生常谈的FactoryBean

    本文完整代码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/factorybean Factory ...

  3. docker进阶1-命令补充和容器卷使用

    命令补充 docker信息与帮助 docker version 和 docker info docker --help 查看所有docker命令列表 docker --help run/commit/ ...

  4. 深入浅出TypeScript(3)- 函数重载和泛型

    面向对象特性中,最根本的就是面向对象的三大基本特征:封装.继承.多态.同时,TypeScript中也存在多态的使用,比如函数重载,今天我们先看一下函数重载以及泛型的概念. 什么是函数重载 简单来说,函 ...

  5. HDU-3400Line belt-三分再三分-求距离中要加esp

    传送门:Line belt 参考:http://blog.csdn.net/hcbbt/article/details/39375763 题意:在一个平面途中,有一条路ab,还有一条路cd:假设在ab ...

  6. CodeForces 765 F Souvenirs 线段树

    Souvenirs 题意:给你n个数, m次询问, 对于每次一次询问, 求出询问区间内绝对值差值的最小值. 题解:先按查询的右端点从小到大sort一下,然后对于塞入一个数的时候, 就处理出所有左端点到 ...

  7. 对JDBC的使用理解

    JDBC,即Java连接数据库,是java针对数据库操作的一套API,使用JDBC对数据库进行操作时分为以下几步: 1.加载数据库驱动类 Class.forName("com.mysql.j ...

  8. lambda表达式分类

    public class StreamTest { public static void main(String[] args) { createStream(); getForEach(); get ...

  9. fastjson对象,JSON,字符串,map之间的互转

    1.对象与字符串之间的互转 将对象转换成为字符串 String str = JSON.toJSONString(infoDo); 字符串转换成为对象 InfoDo infoDo = JSON.pars ...

  10. 使用eclipse Debug时总是被URLClassLoader这个类拦截,不能进入到要调试的类里面去

    打开Debug,如图去掉前面的两个对号,重新debug即可: