并发编程之Event事件
Event事件
事件处理的方法:
event.is_set():返回event的状态值;
event.wait():如果 event.isSet()==False将阻塞线程;
event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
event.clear():恢复event的状态值为False。
事件处理的机制:
首先,全局定义了一个“Flag”
1. 如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞
2. 如果“Flag”值为True,那么event.wait 方法时便不再阻塞。
clear方法:
- 将“Flag”设置为False
set方法:
- 将“Flag”设置为True
代码示例:
from threading import Thread, Event
import time
event = Event()
def student(user):
print(f'{user} 正在上课')
event.wait(2) # 阻塞2s
print(f'{user} 正在上体育课')
def teacher(user):
print(f'{user} 正在讲课中')
time.sleep(5) # 阻塞5s
print(f'{user} 说下课了')
event.set()
if __name__ == '__main__':
stu1 = Thread(target=student, args=('xiao',))
stu2 = Thread(target=student, args=('quan',))
stu3 = Thread(target=student, args=('zheng',))
teacher = Thread(target=teacher, args=('zhao',))
stu1.start()
stu2.start()
stu3.start()
teacher.start()
# xiao 正在上课
# quan 正在上课
# zheng 正在上课
# zhao 正在讲课中
# quan 正在上体育课
# zheng 正在上体育课
# xiao 正在上体育课
# zhao 说下课了
MySQL案例:
## 例如,有多个工作线程尝试链接MySQL,我们想要在链接前确保MySQL服务正常才让那些工作线程去连接MySQL服务器,如果连接不成功,都会去尝试重新连接。那么我们就可以采用threading.Event机制来协调各个工作线程的连接操作
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().name, count))
event.wait(0.5)
count += 1
print('<%s>链接成功' % threading.current_thread().name)
def check_mysql():
print('\033[45m[%s]正在检查mysql\033[0m' % threading.current_thread().name)
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()
import time
from threading import Thread, Event, current_thread
event = Event()
def conn():
n = 0
while not event.is_set():
if n == 3:
print('%s try too many times' % current_thread().name)
return
print('%s try %s' % (current_thread().name, n))
event.wait(0.5)
n += 1
print('%s is connected' % current_thread().name)
def check():
print('%s is checking' % current_thread().name)
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()
# Thread-1 (conn) try 0
# Thread-2 (conn) try 0
# Thread-3 (conn) try 0
# Thread-4 (check) is checking
# Thread-3 (conn) try 1
# Thread-1 (conn) try 1
# Thread-2 (conn) try 1
# Thread-2 (conn) try 2
# Thread-3 (conn) try 2
# Thread-1 (conn) try 2
# Thread-1 (conn) try too many times
# Thread-2 (conn) try too many times
# Thread-3 (conn) try too many times

浙公网安备 33010602011771号