1、Event对象

线程的一个关键特性是每个线程都是独立运行且状态不可预测。
如果程序中的其他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就会变得非常棘手。
为了解决这些问题,我们需要使用threading库中的Event对象。
对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。
在初始情况下,Event对象中的信号标志被设置为假。
如果有线程等待一个Event对象, 而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。
一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。
如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件, 继续执行

  

from threading import Event

event.isSet():返回event的状态值;
event.wait():如果 event.isSet()==False将阻塞线程;
event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
event.clear():恢复event的状态值为False。

  

超时3s中,刷新,重新执行程序等待,信号标志

  

2、Event应用:连接数据库

例如,有多个工作线程尝试链接MySQL,我们想要在链接前确保MySQL服务正常才让那些工作线程去连接MySQL服务器,

如果连接不成功,都会去尝试重新连接。那么我们就可以采用threading.Event机制来协调各个工作线程的连接操作

(1)初级版本

from threading import Thread, Event, currentThread
import time event = Event() def conn():
print('%s is connecting' % currentThread().getName())
event.wait() # 默认是False阻塞中, 等变为True 程序放行
print('%s is connected' % currentThread().getName()) def check():
print('%s is checking' % currentThread().getName())
time.sleep(5)
event.set() # Event对象 的信号标志设置未True if __name__ == '__main__':
for i in range(3):
t = Thread(target=conn)
t.start() t = Thread(target=check)
t.start()

(2)中级版本

# Event 对象,允许线程等待某些事情的发生

from threading import Thread, Event, currentThread
import time event = Event() def conn():
n = 0
while not event.is_set():
print('%s is connecting %s times' % (currentThread().getName(), n))
event.wait(0.5)
if n == 3:
print('%s try more times' % currentThread().getName())
break
n += 1 print('%s is connected' % currentThread().getName()) def check():
print('%s is checking' % currentThread().getName())
time.sleep(5)
event.set() if __name__ == '__main__':
for i in range(3):
t = Thread(target=conn)
t.start() t = Thread(target=check)
t.start()

(3)课件版本

from threading import Thread,Event
import threading
import time,random
def conn_mysql():
count=1
while not event.is_set():
if count > 3:
raise TimeoutError('链接超时')
print('<%s>第%s次尝试链接' % (threading.current_thread().getName(), count))
event.wait(0.5)
count+=1
print('<%s>链接成功' %threading.current_thread().getName()) def check_mysql():
print('\033[45m[%s]正在检查mysql\033[0m' % threading.current_thread().getName())
time.sleep(random.randint(2,4))
event.set()
if __name__ == '__main__':
event=Event()
conn1=Thread(target=conn_mysql)
conn2=Thread(target=conn_mysql)
check=Thread(target=check_mysql) conn1.start()
conn2.start()
check.start()

3、定时器

  (1)验证码功能

from threading import Timer
import time
import random
import string # 验证码功能
# 3s验证码刷新一次 class Code(object):
# 生成一个验证码
def make_code(self):
code_list = random.sample(string.ascii_letters, 4)
self.ret = ''.join(code_list)
print(self.ret) # >> > help(random.sample) 获取帮助
# >> > random.sample(string.ascii_letters, 4)
# ['W', 'B', 'g', 'n'] # 输入一个验证码
def enter_code(self): self.make_code()
choice = input('输入验证码>>>').strip()
if choice.upper() == self.ret.upper():
print('验证成功')
else:
print('验证失败')
if __name__ == '__main__':
c = Code()
c.enter_code()

  

  (2)定时刷新验证码

  (3)课件版本

from threading import Timer
import random class Code(object):
def __init__(self):
self.make_cache() def make_cache(self, interval=5):
self.cache = self.make_code()
print(self.cache)
self.t = Timer(interval, self.make_cache)
self.t.start() def make_code(self, n=4):
ret = ''
for i in range(n):
s1 = str(random.randint(0, 9))
s2 = chr(random.randint(65, 90))
ret += random.choice([s1, s2]) return ret def check(self):
while True:
code = input('输入验证码>>>').strip()
if code.upper() == self.cache:
print('输入成功')
self.t.cancel()
break obj = Code()
obj.check()

4.线程queue

queue is especially useful in threaded programming when information must be exchanged safely between multiple threads.

有三种不同的用法

(1)队列:先进先出

class queue.Queue(maxsize=0) #队列:先进先出

  

(2)堆栈:后进先出

class queue.LifoQueue(maxsize=0) #堆栈:last in fisrt out

(3)优先级队列

class queue.PriorityQueue(maxsize=0) #优先级队列:存储数据时可设置优先级的队列

  

7-[多线程]-Event、定时器、队列、堆栈的更多相关文章

  1. 一个基于C++11的定时器队列(timerfd,poll实现)

    目录 前言 优点 test 源代码 @ 前言 最近小程序要用到定时器,找了一圈也没找到合适的,最后还是绕回来选择了muduo里面的TimerQueue,整理了下它的代码,独立了出来,因为实在懒得从头写 ...

  2. muduo网络库学习笔记(三)TimerQueue定时器队列

    目录 muduo网络库学习笔记(三)TimerQueue定时器队列 Linux中的时间函数 timerfd简单使用介绍 timerfd示例 muduo中对timerfd的封装 TimerQueue的结 ...

  3. iOS多线程中,队列和执行的排列组合结果分析

    本文是对以往学习的多线程中知识点的一个整理. 多线程中的队列有:串行队列,并发队列,全局队列,主队列. 执行的方法有:同步执行和异步执行.那么两两一组合会有哪些注意事项呢? 如果不是在董铂然博客园看到 ...

  4. java多线程:java队列详解

    队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作.进行插入操作的端称为队尾,进行删除操作的端称为队头.队列中没有元素时,称为空队列. 在队列这 ...

  5. JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

    JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序猿杜鹏程的博客:http://blog ...

  6. SQLServer和MySQL job和 event定时器的差别

    SQLServer和MySQL job和 event定时器的差别

  7. RabbitMQ入门_05_多线程消费同一队列

    A. 多线程消费同一队列 参考资料:https://www.rabbitmq.com/tutorials/tutorial-two-java.html 消费一条消息往往比产生一条消息慢很多,为了防止消 ...

  8. ~~并发编程(十三):信号量,Event,定时器~~

    进击のpython ***** 并发编程--信号量,Event,定时器 本节需要了解的就是: 信号量,以及信号量和互斥锁的区别 了解时间和定时器,以及使用 信号量 信号量也是锁,本质没有变!但是他跟互 ...

  9. [Python 多线程] Timer定时器/延迟执行、Event事件 (七)

    Timer继承子Thread类,是Thread的子类,也是线程类,具有线程的能力和特征.这个类用来定义多久执行一个函数. 它的实例是能够延迟执行目标函数的线程,在真正执行目标函数之前,都可以cance ...

  10. 多线程《七》信号量,Event,定时器

    一 信号量 信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,信号量同一时间可以有5个任务拿到锁去执行,如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群 ...

随机推荐

  1. js拼接字符串,字符串转数组

    想要把字符串按一定的规则拼起来如 1,2,3 var a = []; a.push(1); a.push(2); a.push(3); a.join(','); =>> 1,2,3 想要把 ...

  2. 使用CAReplicatorLayer [2]

    使用CAReplicatorLayer [2] 工具类 // // Math.h // MathEquation // // Created by YouXianMing on 15/11/20. / ...

  3. Linux查看系统当前字符集

    常用的命令展示 参考当前环境的字符集 方法一: cat /etc/sysconfig/i18n [ssh客户端工具最好也是utf-8,保持一致] 方法二:echo $LANG 设置当前环境的字符集 方 ...

  4. Linux tar命令详解

    当你想要压缩一大堆文件时,你得先将这一大堆文件先打成一个包(tar命令),然后再用压缩程序进行压缩(gzip bzip2命令) tar常见命令参数 必要参数有如下: -A 新增压缩文件到已存在的压缩 ...

  5. Hadoop HBase概念学习系列之行、行键(十一)

    行是由列簇中的列组成.行根据行键依照字典顺序排序. HBase的行使用行键标识,可以使用行键查询整行的数据. 对同一个行键的访问都会落在同样的物理节点上.如果表包含2个列簇,属于两个列簇的文件还是保存 ...

  6. Take my breath away

    Take my breath away 编辑 目录 1简介 2翻唱简介 3歌词 ▪ 英文歌词 ▪ 中英文歌词 1简介编辑 <Take My Breath Away>(中文译为<带走我 ...

  7. 第二次作业 APP分析

    第一部分 调研, 评测 1.下载软件并使用. 今天我要分析的软件app是UC浏览器这个软件,UC浏览器的用户群体还是挺多的,作为一款主流之一的浏览器APP,整体的用户体验还是很好的.简洁的界面还有中间 ...

  8. 打印pdf

    #include "pdf_print_helper.h" pdf_print_helper::pdf_print_helper(){ } pdf_print_helper::~p ...

  9. PHP获取视频的第一帧与时长

    //获得视频文件的缩略图 function getVideoCover($file,$time,$name) { if(empty($time))$time = '1';//默认截取第一秒第一帧 $s ...

  10. 分布式缓存技术redis系列(一)——redis简介以及linux上的安装

    redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssd ...