线程控制-延时与守护
时间:2019-09-09
本文章向大家介绍线程控制-延时与守护,主要包括线程控制-延时与守护使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
本文解决线程控制的2个场景
1. 线程延时:延迟一定时间,再执行后续程序
2. 两个线程,当一个线程执行时间超过规定时间时,执行另一个线程
场景1:定时器
具体参考 我的博客 后续会写
场景2:继承多线程基类
DelayAction:重写 run 方法,在 run 中延迟
DelayAction2:重写 run 方法,在 run 中延迟,并获取输出
class DelayAction(threading.Thread): # 延时执行某个函数 def __init__(self, sec, func, *args): threading.Thread.__init__(self) self.sec = sec self.func = func self.args = args def run(self): time.sleep(self.sec) apply(self.func, self.args) class DelayAction2(threading.Thread): # 延时执行某个函数,并获取返回 def __init__(self, sec, func, *args): threading.Thread.__init__(self) self.sec = sec self.func = func self.args = args self.res = None def run(self): time.sleep(self.sec) self.res = apply(self.func, self.args) if __name__ == '__main__': ### test DelayAction def myfunc(x): print(x) return 1 da = DelayAction(10, myfunc, 222) da.start() # 10s 后打印 222 ### test DelayAction2 da2 = DelayAction2(10, myfunc, 333) da2.start() # 10s 后打印 333 print(da2.res) # 马上打出 None ,“打印”这个线程和 da2 是并行的,之所以打印出 None,而不是函数值,因为此时函数还没执行呢 da2.join() print(da2.res) # 带函数执行完毕后,打印出 1
场景1 和 2:装饰器实现
timeout:简单例子,方便对比后续
timeout2:用 定时器延时执行了一个回调函数,然而 被装饰的函数并没有被延时,如果加上 t.join 就实现了延时
timeout3:解决了这么一种场景:我需要执行一个函数,如果这个函数某个规定时间内没有执行结束,则强制结束,类似 web 中的 wait
// 这是一个失败的例子,在 callback 中 return,并不能使整个函数结束
timeout4:解决了上述场景,添加了线程守护
def timeout(func): # 被装饰的函数带参数的装饰器 def myfunc(sec): time.sleep(sec) func() return myfunc def timeout2(sec, callback): # 装饰器带参数的装饰器 def _deco(func): t = threading.Timer(sec, callback) # threading.Timer定时器,sec 秒后执行回调函数 t.start() t.join() def myfunc(arg): # 注意这里其实并没有延时 myfunc,这只是一个样例,你可以根据需要自己扩展,如在 函数上一行加上 t.join() func(arg) return myfunc return _deco def timeout3(sec, callback): # 有这么一种场景:我需要执行一个函数,如果这个函数某个规定时间内没有执行结束,则强制结束 【这个函数没有实现需求】 def _deco(func): t = threading.Timer(sec, callback) # callback 假设 10s 结束 t.start() def myfunc(): func() # 被装饰的函数 假设 100s 结束 return myfunc return _deco def timeout4(callback, arg): # 有这么一种场景:我需要执行一个函数,如果这个函数某个规定时间内没有执行结束,则强制结束 【这个函数实现了需求】 def _deco(func): t = threading.Thread(target=callback, args=(arg, )) # callback 假设 10s 结束 t.setDaemon(True) ## 必须有, 线程守护,myfunc 相当于主线程 t.start() def myfunc(): func() # 被装饰的函数 假设 100s 结束 return myfunc return _deco if __name__ == '__main__': ### test timeout @timeout def test(): print(33) # test(10) # 10s 后打印 33 ### test timeout2 def callback(): print('callback2') @timeout2(10, callback) def test2(x): print(x) # test2(100) # 立刻打印出 100, 也就是 test2 立即执行了,并没有被延时 # 10s 后打印出 callback2,回调函数延时执行 ## timeout2 中如果加上 t.join,10s 后立即先后打印了 callback2 100,也就是双重延时 ### 注意理解就行,怎么写看实际需求 ### test timeout3 def callback(): print('callback3') return @timeout3(10, callback) def test3(): time.sleep(100) print('test3') # test3() # 10s 后打印出 callbak2 callback3,100s 后打印出 test3 ## 这里 test2 并没有执行,为什么打印出 callbak2 callback3,后面我会解释 ### test timeout4 def callback(sec): time.sleep(sec) print('callback4') return @timeout4(callback, 100) # 这里是线程守护,10s 的线结束,100s 的自动结束,故主线程是时间短的线程 def test4(): time.sleep(10) print('test4') test4()
注意,时间长的线程被守护。
这里对装饰器简单总结2点
1. 装饰器,就是修饰一个函数,所有一定有一层是只输入一个 func
2. 装饰器首先执行的是装饰的函数 deco,并且 deco 永远是顶层函数 【解决上面 ‘打印出 callbak2 callback3’ 的问题】
import threading def timeout2(sec, callback): # 装饰器带参数的装饰器 def _deco(func): t = threading.Timer(sec, callback) t.start() # t.join() def myfunc(arg): func(arg) return myfunc return _deco def callback(): print('callback2') @timeout2(1, callback) # 立即打印 callback2,并结束 def test2(x): print(x)
并没有执行任何函数,而 deco 被自动执行。
场景2:线程守护简单版
import time import threading def func1(): time.sleep(10) print('func1') return 1 def func2(): time.sleep(20) print('func2') return 2 def test(): t2 = threading.Thread(target=func2) # 慢的线程,作为守护线程 t2.setDaemon(True) t2.start() func1() test() # 10s 后打印 func1,当快的线程结束时,慢的线程自动结束
这里可以重写 run 方法,获取 func2 的输出,根据需求自行扩展。
原文地址:https://www.cnblogs.com/yanshw/p/11490876.html
- 微信JSSDK接入Java版--步骤及问题处理和解决
- 微信企业号回调模式配置讲解 Java Servlet+Struts2版本 echostr校验失败解决
- Android Material Design系列之RecyclerView和CardView
- 在Linux安装ASP.Net Core的运行时(Runtime)
- 使用xUnit为.net core程序进行单元测试(下1)
- Otto开发初探——微服务依赖管理新利器
- Apache Eagle——eBay开源分布式实时Hadoop数据安全方案
- Spring/Hibernate 应用性能优化的7种方法
- 浅谈应用型机器学习作为一种搜索问题
- 自相关和偏自相关的简单介绍
- 机器学习中分类与回归的差异
- 自然语言处理指南(第1部分)
- GreenDao 兼容升级,保留旧数据的---全方面解决方案
- 基于 xorm 的服务端框架 XGoServer
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Laravel5.1 框架Request请求操作常见用法实例分析
- 用python实现学生管理系统
- PHP CURL实现模拟登陆并上传文件操作示例
- python定义类的简单用法
- Linux yum 命令安装mysql8.0的教程详解
- 基于Python实现简单学生管理系统
- php 实现svg转化png格式的方法分析
- Python如何合并多个字典或映射
- 用Python 爬取猫眼电影数据分析《无名之辈》
- Python获取浏览器窗口句柄过程解析
- python如何支持并发方法详解
- thinkPHP+mysql+ajax实现的仿百度一下即时搜索效果详解
- php和C#的yield迭代器实现方法对比分析
- Python字符串函数strip()原理及用法详解
- python中取绝对值简单方法总结