Python使用装饰器和线程限制函数执行时间的方法
前言:
(不想看废话的可以直接copy尾部的代码)在八月上旬的时候,曾经写过一个多线程爬虫。程序在运行时经常莫名的卡死。这令我很是费解,后来才发现,是在请求对方资源时,服务器长时间未返回完数据。导致IO阻塞。其实不只是爬虫,很多时候一个函数很可能因为某种不可预知的事情,而有时很可能会卡在某一处,继而函数无法继续执行下去。导致拥塞。此时,我们自然而然的会想到如果能写一个装饰器来限制一个函数执行的时间,那么问题也就迎刃而解了。
正文:
最初,因为我的拥塞是发生在多进程中,我曾经想通过杀死线程的方式来解决问题。然而python中的threading模块中并没有提供这一方法。网上有类似方法,但是比较繁琐。并且非常不建议直接杀死线程(这其中可能关系到资源释放的问题,比如我从队列中取出了一个url, 然而我的进程卡死了,并没有完成相应的任务,我却强行得终止了这个线程,url中的内容未采集,url也没用放回到队列中,岂不是造成了资源的浪费)。后来想到可以直接对函数的运行时间进行限制,这样就省了不少事情。
方法一:
此方法比较容易理解,写了一个装饰器,看到其中的__wrapper函数,新建了一个守护线程,target是我们需要限制时间的函数。启动守护线程之后,主线程sleep(timer)(timer就是我们设定的函数运行时间)。若在规定的运行时间未结束守护进程(也就是我们需要限制运行时间的函数),则主动抛出异常。(但此种方法有一个弊端,就是如果函数在目标时间内运行完了,由于sleep的原因,整个线程还是会等到sleep(timer)后结束,可能会浪费时间)
#!/usr/bin/env python
#-*- coding:utf-8 -*-
#Author: Chen
import threading
import timedef time_limited(timer):'''一个规定函数执行时间的装饰器:param timer::return:'''def wrapper(func):def __wrapper(params):start_time = time.time()#通过设置守护线程强制规定函数的运行时间t = threading.Thread(target=func, args=params)t.setDaemon(True)t.start()time.sleep(timer)if t.is_alive():#若在规定的运行时间未结束守护进程,则主动抛出异常raise Exception('Function execution timeout')#print time.time()-start_timereturn __wrapperreturn wrapper
第二种:
此种方法是第一种的升级,改进了函数运行完不结束的弊端
#!/usr/bin/env python
#-*- coding:utf-8 -*-
#Author: Chen
import time
from threading import ThreadThreadStop = Thread._Thread__stop#获取私有函数
def time_limited_pri(time_limited):def wrapper(func):def __wrapper(params):class TimeLimited(Thread):def __init__(self):Thread.__init__(self)def run(self):func(params)def _stop(self):if self.is_alive():ThreadStop(self)raise Exception('Function execution overtime')t = TimeLimited()t.start()t.join(timeout=time_limited)if t.is_alive():t._stop()raise Exception('Function execution overtime')return __wrapperreturn wrapper
作者:CCCCmaster链接:https://www.jianshu.com/p/ae9c29bac54f來源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Python使用装饰器和线程限制函数执行时间的方法相关推荐
- python中的json函数_python中装饰器、内置函数、json的详解
装饰器 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象. 先看简单例子: def run(): time.sleep(1 ...
- python中装饰器的作用_Python装饰器详解,详细介绍它的应用场景
装饰器的应用场景附加功能 数据的清理或添加:函数参数类型验证 @require_ints 类似请求前拦截数据格式转换 将函数返回字典改为 JSON/YAML 类似响应后篡改为函数提供额外的数据 moc ...
- python装饰器模式带参数_Python装饰器使用实例:验证参数合法性 请教Python 使用装饰器实现单例模式的原理...
python中一层装饰器的函数可以带参数吗 可以的, 装饰器分为可带参数和不可带参数的两种:但是如果带参数,则带参数装饰器的"参数"及"return"必须也是一 ...
- python单例模式原理-请教Python 使用装饰器实现单例模式的原理
扩展回答 如何理解Python装饰器 简单来讲,可以不严谨地把Python的装饰器看做一个包装函数的函数. 比如,有一个函数: def func(): print "func() run.& ...
- python装饰器实现单例模式_请教Python 使用装饰器实现单例模式的原理
1 简单来讲,可以不严谨地把Python的装饰器看做一个包装函数的函数. 比如,有一个函数: def func(): print 'func() run.' if '__main__' == __na ...
- python装饰器使用教学,Python教程|简单上手Python中装饰器的使用
如何打造极简主义风格网站教程 .极简主义与其他设计风格<极简主义设计之美> 这篇文章的一部分是讲极简主义是如何与其他设计风格很好配合的.可以把极简主义当作一种属性,而它可以添加或结合其他. ...
- Python装饰器是什么?使用Python装饰器实现计算程序(函数)运行时间的功能
Python装饰器是什么?使用Python装饰器实现计算程序(函数)运行时间的功能 目录
- python装饰器函数-Python精进-装饰器与函数对象
本文为<爬着学Python>系列第四篇文章. 从本篇开始,本专栏在顺序更新的基础上,会有不规则的更新. 在Python的学习与运用中,我们迟早会遇到装饰器,这个概念对于初识装饰器的新手来说 ...
- Python: 使用装饰器“@”取得函数执行时间
class A(): Python: 使用装饰器"@"取得函数执行时间 - oldJ的学习笔记 - 博客频道 - CSDN.NET Python: 使用装饰器"@&quo ...
最新文章
- Codeforces Round #409 (Div. 2) C Voltage Keepsake(二分)
- Python 技巧篇-让我的程序暂停一下
- Git之深入解析如何重写提交历史
- Go语言入门指南,带你轻松学Go
- xampp php连接mysql数据库_关于PHP xampp连接数据库之后查询失败,数据库连接成功,表中也有数据...
- linux 输入是否为数字,【shell】Linux shell 之 判断用户输入的变量是否为数字
- 算法设计与分析———动态规划———最大子段和
- MS SQL 能否修改实例名称
- java bean状态_无状态和有状态企业Java Bean
- 返回一个整数数组中最大子数组的和---环形数组
- 学习笔记(01):Oracle数据库-Oracle安装与配置
- 真正无人驾驶有望在美国全境普及?美交通部准备修改安全法规
- Spring 创建代理类流程跟踪
- 问题五十:怎么用ray tracing画blobs
- 数据库修改后 前台同步更新 php,PHP实现前台页面与MySQL的数据绑定、同步更新...
- 四因素三水平正交试验表_正交实验设计过程
- dedecms关于访问量的修改
- c实现一个简单的线性反馈移位寄存器LFSR
- 使用 HTML、CSS 和 JS 的简单倒数计时器
- 极虎病毒:虎年第一猛毒详解