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。

[Python 多线程] Timer定时器/延迟执行、Event事件 (七)的更多相关文章

  1. Python 中Semaphore 信号量对象、Event事件、Condition

    Semaphore 信号量对象 信号量是一个更高级的锁机制.信号量内部有一个计数器而不像锁对象内部有锁标识,而且只有当占用信号量的线程数超过信号量时线程才阻塞.这允许了多个线程可以同时访问相同的代码区 ...

  2. python下timer定时器常用的两种实现方法

    方法一,使用线程中现成的:   这种一般比较常用,特别是在线程中的使用方法,下面是一个例子能够很清楚的说明它的具体使用方法: #! /usr/bin/python3 #! -*- conding: u ...

  3. Python多线程thread、threading(一)

    Python多线程(一) Python多线程,类似于同时执行多个不同程序,多线程运行的有点: 1.使用线程可以把占据长时间的程序中的任务放到后台去处理 2.用户界面可以更加吸引人,这样比如用户点击了一 ...

  4. Python基础(十三) 为什么说python多线程没有真正实现多现程

    Python中的多线程没有真正实现多现程! 为什么这么说,我们了解一个概念,全局解释器锁(GIL). Python代码的执行由Python虚拟机(解释器)来控制. Python在设计之初就考虑要在主循 ...

  5. Python之路(第四十五篇)线程Event事件、 条件Condition、定时器Timer、线程queue

    一.事件Event Event(事件):事件处理的机制:全局定义了一个内置标志Flag,如果Flag值为 False,那么当程序执行 event.wait方法时就会阻塞,如果Flag值为True,那么 ...

  6. python并发编程-多线程实现服务端并发-GIL全局解释器锁-验证python多线程是否有用-死锁-递归锁-信号量-Event事件-线程结合队列-03

    目录 结合多线程实现服务端并发(不用socketserver模块) 服务端代码 客户端代码 CIL全局解释器锁****** 可能被问到的两个判断 与普通互斥锁的区别 验证python的多线程是否有用需 ...

  7. Python多线程-Event(事件对象)

    Event 事件对象管理一个内部标志,通过set()方法将其设置为True,并使用clear()方法将其设置为False.wait()方法阻塞,直到标志为True.该标志初始为False. 方法: i ...

  8. Node.js实战6:定时器,使用timer延迟执行。

    setTimeout 在nodejs中,通过setTimeout函数可以达到延迟执行的效果,这个函数也常被称为定时器. 一个简单的例子: console.log( (new Date()).getSe ...

  9. 并发编程 - 线程 - 1.互斥锁/2.GIL解释器锁/3.死锁与递归锁/4.信号量/5.Event事件/6.定时器

    1.互斥锁: 原理:将并行变成串行 精髓:局部串行,只针对共享数据修改 保护不同的数据就应该用不用的锁 from threading import Thread, Lock import time n ...

随机推荐

  1. 解决-word里无论怎么改变字体颜色,字体总是红色的

    1.你遇到的问题是Word当前处于审阅状态,修改的内容显示为红色字体.2.解决办法是退出Word审阅状态,或者接受全部修订.3.不同Word版本的审阅模式不同,可在菜单栏里退出审阅,或者按鼠标右键弹出 ...

  2. Java面试题之数据库三范式是什么?

    什么是范式? 简言之就是,数据库设计对数据的存储性能,还有开发人员对数据的操作都有莫大的关系.所以建立科学的,规范的的数据库是需要满足一些规范的来优化数据数据存储方式.在关系型数据库中这些规范就可以称 ...

  3. 前端(十一):props、state及redux关系梳理

    所谓状态机,是一种抽象的数据模型,是“事物发展的趋势”,其原理是事件驱动.广泛地讲,世界万物都是状态机. 一.状态机是一种抽象的数据模型 在react中,props和state都可以用来传递数据.这里 ...

  4. Hibernate入门(三)—— 一对多、多对多关系

    一.一对多关系 1.概念 ​ 一对多关系是关系型数据库中两个表之间的一种关系.通常在数据库层级中,两表之间是有主外键关系的.在ORM中,如何通过对象描述表之间的关系,是ORM核心. 2.Hiberna ...

  5. GIS 地理坐标分类

    wgs84 GPS系统直接通过卫星定位获得的坐标.(最基础的坐标.) gcj02 兲朝已安全原因为由,要求在中国使用的地图产品使用的都必须是加密后的坐标.这套加密后的坐标就是gcj02 google的 ...

  6. Intellij IDEA通过SVN导入基于Springboot的maven项目以及对已有项目做更新

    一.导入外部maven项目 点击“+”,输入SVN地址并下载项目 弹出窗口,选择new window(自己觉得哪个好就选哪个) 等待执行完毕,执行完后会出现以下情况,就需要配置一下你的maven库了 ...

  7. Vue实例对象的数据选项(火柴)

    前言 一般地,当模板内容比较简单的时候,使用data选项配合表达式即可.涉及到复杂逻辑时,则需要用到methods.computed.watch等方法.本文将详细介绍Vue实例对象的数据选项. dat ...

  8. SpringMVC中使用DispatcherServlet

    接触Web开发的时候我们会利用Servlet来接收和转发前端页面的各种请求,我们通常会在一个页面中对应一个Servlet来处理这个页面上和用户交互的信息,通常我门遇到5个以内的页面自己来写Servle ...

  9. Django objects.all() ,objects.get() ,objects.filter()之间的区别

    ret=UserInfo.objects.all() all返回的是QuerySet对象,程序并没有真的在数据库中执行SQL语句查询数据,但支持迭代,使用for循环可以获取数据. ret=UserIn ...

  10. SQL Server ->> 高可用与灾难恢复(HADR)技术之 -- Windows故障转移群集

    WSFC 群集 (WSFC cluster)“Windows Server 故障转移群集”(WSFC) 群集是一组独立的服务器,它们共同协作以提高应用程序和服务的可用性. 故障转移群集实例 (Fail ...