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. C#实现字符串计算

    借用DataTable的Compute函数进行计算. string formula = "1+1*4/3+23*(1+2)"; DataTable dt = new DataTab ...

  2. 动态将彩色图片动画过渡到黑白图片的BlackAndWhiteView

    动态将彩色图片动画过渡到黑白图片的BlackAndWhiteView 效果如下: BlackAndWhiteView.h 与 BlackAndWhiteView.m // // BlackAndWhi ...

  3. Linux alias命令详解

    alias:内置命令(没有路径),设置命令的别名,保护系统,方便 unalias:别名取消 常用的命令展示 临时设置 alias cp='cp –i' unalias cp      取消系统的别命令 ...

  4. windows 查看端口号,杀进程

    查看端口号: 开始--运行--cmd netstat –and 杀进程: windows任务管理器         查看--显示列-PID 相关知识: 一台机器的80端口被httpd (apache) ...

  5. APP案例分析——嘀嗒番茄钟

    第一部分 调研, 评测 个人第一次上手体验 一直在用时间管理的软件,但是下载了卸载,来来去去也用了很多个.这个嘀嗒番茄钟也是最近比较喜欢的软件,界面简洁,功能简单,没有那么复杂非常容易上手. 功能性的 ...

  6. 动态代理与HOOK(与oc isa 替换)

    HOOK:面向函数,解决函数调用拦截与替换的问题: 动态代理:面向对象,解决对象的动态替换问题: 动态代理的实现方案: 1.经典代理机制: 2.子类化机制:oc语言的isa替换是这额解决方案的经典案例 ...

  7. 【openjudge】【递推】例3.6 过河卒(Noip2002)

    [题目描述] 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上的某一点有一个对方的马(如C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点,如图3-1 ...

  8. 随手练——博弈论入门 leetcode - 486. Predict the Winner

    题目链接:https://leetcode.com/problems/predict-the-winner/ 1.暴力递归 当前数组左边界:i,右边界:j: 对于先发者来说,他能取到的最大值是:max ...

  9. 20155314 2016-2017-2 《Java程序设计》第2周学习总结

    20155314 2016-2017-2 <Java程序设计>第2周学习总结 教材学习内容总结 学习目标 了解Java编程风格 认识Java的类型与变量 掌握Java流程控制的方法(分支. ...

  10. 造成MySQL全表扫描的原因

    全表扫描是数据库搜寻表的每一条记录的过程,直到所有符合给定条件的记录返回为止.通常在数据库中,对无索引的表进行查询一般称为全表扫描:然而有时候我们即便添加了索引,但当我们的SQL语句写的不合理的时候也 ...