详解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中使用socket发送HTTP请求数据接收不完整问题解决方法
Feb 04 Python
Python脚本实现格式化css文件
Apr 08 Python
python 如何快速找出两个电子表中数据的差异
May 26 Python
wxpython实现图书管理系统
Mar 12 Python
Form表单及django的form表单的补充
Jul 25 Python
Python如何将图像音视频等资源文件隐藏在代码中(小技巧)
Feb 16 Python
Django 拼接两个queryset 或是两个不可以相加的对象实例
Mar 28 Python
Django实现celery定时任务过程解析
Apr 21 Python
python实现三壶谜题的示例详解
Nov 02 Python
Python模拟登录requests.Session应用详解
Nov 17 Python
python如何获取网络数据
Apr 11 Python
python中 .npy文件的读写操作实例
Apr 14 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
DC游戏Steam周三特惠 《蝙蝠侠》阿卡姆系列平史低
2020/04/09 欧美动漫
mysql下创建字段并设置主键的php代码
2010/05/16 PHP
PHP文件读写操作之文件写入代码
2011/01/13 PHP
PHP学习笔记之三 数据库基本操作
2011/01/17 PHP
php cookies中删除的一般赋值方法
2011/05/07 PHP
destoon设置自定义搜索的方法
2014/06/21 PHP
PHP ignore_user_abort函数详细介绍和使用实例
2014/07/15 PHP
javascript+php实现根据用户时区显示当地时间的方法
2015/03/11 PHP
PHP中is_file()函数使用指南
2015/05/08 PHP
[原创]php求圆周率的简单实现方法
2016/05/30 PHP
thinkPHP自动验证、自动添加及表单错误问题分析
2016/10/17 PHP
Laravel框架实现定时Task Scheduling例子
2019/10/22 PHP
tp5.1 框架数据库-数据集操作实例分析
2020/05/26 PHP
JavaScript delete操作符应用实例
2009/01/13 Javascript
一个简单的弹性返回顶部JS代码实现介绍
2013/06/09 Javascript
利用javascript实现禁用网页上所有文本框,下拉菜单,多行文本域
2013/12/14 Javascript
JavaScript如何实现组合列表框中元素移动效果
2016/03/01 Javascript
使用JSON作为函数的参数的优缺点
2016/10/27 Javascript
实用的 vue tags 创建缓存导航的过程实现
2020/12/03 Vue.js
windows下python安装pip图文教程
2018/05/25 Python
Django RBAC权限管理设计过程详解
2019/08/06 Python
python求解汉诺塔游戏
2020/07/09 Python
python给视频添加背景音乐并改变音量的具体方法
2020/07/19 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
Python字符串三种格式化输出
2020/09/17 Python
HTML5 常见面试题之PC端和移动端区别介绍
2018/01/22 HTML / CSS
美国家用电器和电子产品商店:Abt
2016/09/06 全球购物
Reebonz中国官网:新加坡奢侈品购物网站
2017/03/17 全球购物
Saucony澳大利亚官网:美国跑鞋品牌,运动鞋中的劳斯莱斯
2018/05/05 全球购物
饿了么订餐官网:外卖、网上订餐
2019/06/28 全球购物
what is the difference between ext2 and ext3
2013/11/03 面试题
经济类毕业生求职信
2014/06/26 职场文书
教师节获奖感言
2015/07/31 职场文书
pygame面向对象的飞行小鸟实现(Flappy bird)
2021/04/01 Python
Oracle更换为MySQL遇到的问题及解决
2021/05/21 Oracle
Python+腾讯云服务器实现每日自动健康打卡
2021/12/06 Python