详解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 相关文章推荐
在windows下快速搭建web.py开发框架方法
Apr 22 Python
Python制作刷网页流量工具
Apr 23 Python
Python创建普通菜单示例【基于win32ui模块】
May 09 Python
Python获取昨天、今天、明天开始、结束时间戳的方法
Jun 01 Python
Flask框架WTForm表单用法示例
Jul 20 Python
python使用MQTT给硬件传输图片的实现方法
May 05 Python
Pyqt5 实现跳转界面并关闭当前界面的方法
Jun 19 Python
Python threading的使用方法解析
Aug 28 Python
Django ORM实现按天获取数据去重求和例子
May 18 Python
使用python脚本自动生成K8S-YAML的方法示例
Jul 12 Python
Python 常用日期处理 -- calendar 与 dateutil 模块的使用
Sep 02 Python
PyCharm 安装与使用配置教程(windows,mac通用)
May 12 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中取得URL的根域名的代码
2011/03/23 PHP
php实现遍历目录并删除指定文件中指定内容
2015/01/21 PHP
Zend Framework教程之响应对象的封装Zend_Controller_Response实例详解
2016/03/07 PHP
php获取当前月与上个月月初及月末时间戳的方法
2016/12/05 PHP
php求数组全排列,元素所有组合的方法总结
2017/03/14 PHP
PHP实现的简单适配器模式示例
2017/06/22 PHP
PHP实现Huffman编码/解码的示例代码
2018/04/20 PHP
PHP上传图片到数据库并显示的实例代码
2019/12/20 PHP
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
Js基础学习资料
2010/11/23 Javascript
Jquery 获取checkbox的checked问题
2011/11/16 Javascript
jQuery中.live()方法的用法深入解析
2013/12/30 Javascript
js实现页面跳转的几种方法小结
2016/05/16 Javascript
JavaScript制作颜色反转小游戏
2016/09/25 Javascript
jQuery序列化表单成对象的简单实现
2016/11/29 Javascript
javascript实现数据双向绑定的三种方式小结
2017/03/09 Javascript
JavaScript实现三级联动菜单实例代码
2017/06/26 Javascript
详解webpack中的hash、chunkhash、contenthash区别
2018/01/05 Javascript
图片文字识别(OCR)插件Ocrad.js教程
2018/11/26 Javascript
微信小程序实现渐入渐出动画效果
2019/06/13 Javascript
跟老齐学Python之集成开发环境(IDE)
2014/09/12 Python
深入了解Python数据类型之列表
2016/06/24 Python
python批量获取html内body内容的实例
2019/01/02 Python
linux环境中没有网络怎么下载python
2019/07/07 Python
Tensorflow tf.dynamic_partition矩阵拆分示例(Python3)
2020/02/07 Python
python+requests接口压力测试500次,查看响应时间的实例
2020/04/30 Python
详解Python直接赋值,深拷贝和浅拷贝
2020/07/09 Python
Python tkinter制作单机五子棋游戏
2020/09/14 Python
python实现代码审查自动回复消息
2021/02/01 Python
俄罗斯花园种植材料批发和零售网上商店:Беккер
2019/07/22 全球购物
英国的一家创新礼品和小工具零售商:Menkind
2019/08/24 全球购物
非常详细的C#面试题集
2016/07/13 面试题
医学专业毕业生推荐信
2013/11/14 职场文书
铅球加油稿100字
2014/09/26 职场文书
人民调解协议书范本
2014/10/11 职场文书
女方离婚起诉书
2015/05/18 职场文书