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. springMVC入门-02

    本节会在上节基础上讨论springMVC如何传值的问题. 在添加dispatcherServlet之后,拦截器会将url中的参数拦截下来,使之可以在controller中使用.以下代码就是在前台输入u ...

  2. EF实体对象解耦 - 泛型联表查询

    为了达到模块间最小耦合,单模块业务数据不与其他模块发生关系.在操作数据库的时候,采用EF泛型操作.但泛型操作不好实现联表,经过一晚的试验发现了一种定义数据库上下文并联表的方式. 1.实体对象定义.实体 ...

  3. 从MySQL向Greenplum集群中导入数据

    我们要从MySQL当中导出数据到Greenplum当中,按照以下步骤就可以 1:将MySQL当中的表导出外部文件 以schema_name.table_name为例 select product_id ...

  4. [翻译] popping

    https://github.com/schneiderandre/popping Popping is a collection of animation examples for iOS apps ...

  5. 使用AKLocationManager定位

    使用AKLocationManager定位 https://github.com/ideaismobile/AKLocationManager 以下是使用情况: 是不是很简单呢,我们可以将它的步骤进一 ...

  6. 多线程应用-类(thread)

    在对class thread加锁时,锁无法正常应用,函数方式没问题. 在使用class thread方法时,并发后的查询结果不对,函数方式没问题. # -*- coding: UTF-8 -*- fr ...

  7. PowerShell管理SCOM_批量设置维护模式(上 )

    #定义存储需要置为维护模式的计算机名称列表 $serverlist = "C:\scomm\servers.txt" #定义脚本执行结果的输出位置 $server_maintena ...

  8. Language-Directed Hardware Design for Network Performance Monitoring——Marple

    网络监控困难 1.仅仅通过去增加特定的监控功能到交换机是不能满足运营商不断变化的需求的.(交换机需要支持网络性能问题的表达语言) 2.他们缺乏对网络深处的性能问题进行本地化的可见性,间接推断网络问题的 ...

  9. Eclipse validation

    window->preferences->validation 可以取消部分文件的验证,取消build时验证,改为手动验证,提高效率.

  10. 针对 Linux 环境下 gdb 动态调试获取的局部变量地址与直接运行程序时不一致问题的解决方案

    基础的缓冲区溢出实践通常需要确定运行状态下程序中的某些局部变量的地址,如需要确定输入缓冲区的起始地址从而获得注入缓冲区中的机器指令的起始地址等.在 Linux 环境下,可通过 gdb 对程序进行动态调 ...