详解Python 多线程 Timer定时器/延迟执行、Event事件


Posted in Python onJune 27, 2019

Timer继承子Thread类,是Thread的子类,也是线程类,具有线程的能力和特征。这个类用来定义多久执行一个函数。

它的实例是能够延迟执行目标函数的线程,在真正执行目标函数之前,都可以cancel它。

Timer源码:

class Timer(Thread):
 def __init__(self, interval, function, args=None, kwargs=None):
  Thread.__init__(self)
  self.interval = interval
  self.function = function
  self.args = args if args is not None else []
  self.kwargs = kwargs if kwargs is not None else {}
  self.finished = Event()
 def cancel(self):
  """Stop the timer if it hasn't finished yet."""
  self.finished.set()
 def run(self):
  self.finished.wait(self.interval)
  if not self.finished.is_set():
   self.function(*self.args, **self.kwargs)
  self.finished.set()

Timer类使用方法与Thread定义子线程一样,interval传入间隔时间,function传入线程执行的函数,args和kwargs传入函数的参数。

提前cancel:

import threading
import time
def add(x,y):
 print(x+y)
t = threading.Timer(10,add,args=(4,5))
t.start()
time.sleep(2)
t.cancel()
print("===end===")

运行结果:

===end===

start方法执行之后,Timer对象会处于等待状态,等待10秒之后会执行add函数。同时,在执行add函数之前的等待阶段,主线程使用了子线程的cancel方法,就会跳过执行函数结束。

使用event 事件实现Timer计时器:

import threading
import logging
import time
logging.basicConfig(level=logging.INFO)
# class MyTimer(threading.Thread):
class MyTimer:
 def __init__(self,interval,fn,args=None):
  self.interval = interval
  self.fn = fn
  self.args = args
  self.event = threading.Event()
 def start(self):
  threading.Thread(target=self.__do).start()
 def cancel(self):
  self.event.set()
 def __do(self):
  self.event.wait(self.interval)
  if not self.event.is_set():
   self.fn(*self.args)
def add(x,y):
 logging.warning(x+y)
t = MyTimer(5,add,(4,5))
t.start()
# time.sleep(2)
# t.cancel()

运行结果:

WARNING:root:9

Event事件,是线程间通信机制中最简单的实现,使用一个内部的标记flag,通过flag的True或False的变化来进行操作。

Event源码:

class Event:

def __init__(self):
  self._cond = Condition(Lock())
  self._flag = False
 def _reset_internal_locks(self):
  self._cond.__init__(Lock())
 def is_set(self):
  return self._flag
 isSet = is_set
 def set(self):
  with self._cond:
   self._flag = True
   self._cond.notify_all()
 def clear(self):
  with self._cond:
   self._flag = False
 def wait(self, timeout=None):
  with self._cond:
   signaled = self._flag
   if not signaled:
    signaled = self._cond.wait(timeout)
   return signaled

Event 方法:

•set()                    flag设置为True
•clear()                 flag设置为False
•is_set()                flag是否为True,返回布尔值
•wait(timeout=None)  设置等待flag变为True的时长,None为无限等待。等到了返回True,未等到超时了就返回False。

举例:

老板雇佣了一个工人,让他生产杯子,老板一直等着工人,直到生产了10个杯子。

import threading
import logging
import time
logging.basicConfig(level=logging.INFO)
cups = []
event = threading.Event()#event对象
def boss(e:threading.Event):
 if e.wait(30):#最多等待30秒
  logging.info('Good job.')
def worker(n,e:threading.Event):
 while True:
  time.sleep(0.5)
  cups.append(1)
  logging.info('make 1')
  if len(cups) >=n:
   logging.info('I finished my job. {}'.format(len(cups)))
   e.set()#flag设置为True
   break
b = threading.Thread(target=boss,name='boos',args=(event,))
w = threading.Thread(target=worker,args=(10,event))
w.start()
b.start()

运行结果:

INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:I finished my job. 10
INFO:root:Good job.

老板和工人使用同一个Event对象的标记flag。

老板wait()设置为最多等待30秒,等待flag变为True,工人在做够10杯子时,将flag设置为True,工人必须在30秒之内没有做好杯子。

wait的使用:

import threading
import logging
logging.basicConfig(level=logging.INFO)
def do(event:threading.Event,interval:int):
 while not event.wait(interval): # not event.wait(1) = True
  logging.info('To do sth.')
e = threading.Event()
t = threading.Thread(target=do,args=(e,1))
t.start()
e.wait(10) # 也可以使用time.sleep(10)
e.set()
print('Man Exit.')

运行结果:

INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
Man Exit.

wait与sleep的区别是:wait会主动让出时间片,其它线程可以被调度,而sleep会占用时间片不让出。

小结:

Timer定时器继承自Thread类,也是线程类。它的作用是等待n秒钟之后执行某个目标函数,可以使用cancel提前取消。

Event事件是通过True和False维护一个flag标记值,通过这个标记的值来决定做某事,wait()方法可以设置最长等待flag设置为Ture的时长,超时还未设置为True就返回False。

PS:下面看下python之定时器Timer

timer类

Timer(定时器)是Thread的派生类,用于在指定时间后调用一个方法。

构造方法:

Timer(interval, function, args=[], kwargs={}) 
interval: 指定的时间 

function: 要执行的方法 

args/kwargs: 方法的参数

实例方法:

Timer从Thread派生,没有增加实例方法。

例子一:

# encoding: UTF-8
import threading
def func():
  print 'hello timer!'
timer = threading.Timer(5, func)
timer.start()

线程延迟5秒后执行。

总结

以上所述是小编给大家介绍的详解Python 多线程 Timer定时器/延迟执行、Event事件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python内置函数 next的具体使用方法
Nov 24 Python
用Python下载一个网页保存为本地的HTML文件实例
May 21 Python
TensorFlow实现简单卷积神经网络
May 24 Python
flask框架自定义url转换器操作详解
Jan 25 Python
浅谈Python的方法解析顺序(MRO)
Mar 05 Python
python 实现仿微信聊天时间格式化显示的代码
Apr 17 Python
解决安装新版PyQt5、PyQT5-tool后打不开并Designer.exe提示no Qt platform plugin的问题
Apr 24 Python
Matplotlib自定义坐标轴刻度的实现示例
Jun 18 Python
Matplotlib中%matplotlib inline如何使用
Jul 28 Python
Django URL参数Template反向解析
Nov 24 Python
python 调用Google翻译接口的方法
Dec 09 Python
Python趣味挑战之实现简易版音乐播放器
May 28 Python
python pytest进阶之fixture详解
Jun 27 #Python
解决pycharm 远程调试 上传 helpers 卡住的问题
Jun 27 #Python
python中pytest收集用例规则与运行指定用例详解
Jun 27 #Python
python取余运算符知识点详解
Jun 27 #Python
如何运行.ipynb文件的图文讲解
Jun 27 #Python
python的pytest框架之命令行参数详解(下)
Jun 27 #Python
python的pytest框架之命令行参数详解(上)
Jun 27 #Python
You might like
百度工程师讲PHP函数的实现原理及性能分析(二)
2015/05/13 PHP
PHP使用new StdClass()创建空对象的方法分析
2017/06/06 PHP
使用 JScript 创建 .exe 或 .dll 文件的方法
2011/07/13 Javascript
jquery 新建的元素事件绑定问题解决方案
2014/06/12 Javascript
javascript函数中参数传递问题示例探讨
2014/07/31 Javascript
JS制作手机端自适应缩放显示
2015/06/11 Javascript
js实现头像图片切割缩放及无刷新上传图片的方法
2015/07/17 Javascript
jquery动态导航插件dynamicNav用法实例分析
2015/09/06 Javascript
javascript跨域的方法汇总
2015/10/23 Javascript
使用JQuery FancyBox插件实现图片展示特效
2015/11/16 Javascript
分享15个大家都熟知的jquery小技巧
2015/12/02 Javascript
浅析BootStrap模态框的使用(经典)
2016/04/29 Javascript
对javascript继承的理解
2016/10/11 Javascript
javascript事件的传播基础实例讲解(35)
2017/02/14 Javascript
BootStrap Fileinput上传插件使用实例代码
2017/07/28 Javascript
AngularJs+Bootstrap实现漂亮的计算器
2017/08/10 Javascript
结合Vue控制字符和字节的显示个数的示例
2018/05/17 Javascript
JavaScript面向对象的程序设计(犯迷糊的小羊)
2018/05/27 Javascript
浅谈vue后台管理系统权限控制思考与实践
2018/12/19 Javascript
用Electron写个带界面的nodejs爬虫的实现方法
2019/01/29 NodeJs
nodejs微信开发之自动回复的实现
2019/03/17 NodeJs
[01:45]DOTA2众星出演!DSPL刀塔次级职业联赛宣传片
2014/11/21 DOTA
跟老齐学Python之使用Python操作数据库(1)
2014/11/25 Python
Python实现一个服务器监听多个客户端请求
2018/04/12 Python
python 获取当天每个准点时间戳的实例
2018/05/22 Python
python地震数据可视化详解
2019/06/18 Python
python3.6 tkinter实现屏保小程序
2019/07/30 Python
python线程中的同步问题及解决方法
2019/08/29 Python
Python读写锁实现实现代码解析
2020/11/28 Python
纯CSS实现设置半个字符的样式
2014/07/03 HTML / CSS
娇韵诗加拿大官网:Clarins加拿大
2017/11/20 全球购物
Merrell美国官网:美国登山运动鞋品牌
2018/02/07 全球购物
西部世纪面试题
2014/12/05 面试题
什么是符号链接,什么是硬链接?符号链接与硬链接的区别是什么?
2013/05/03 面试题
社团招新策划书
2014/02/04 职场文书
三分钟演讲稿事例
2014/03/03 职场文书