day9-event(红绿灯例子)
背景
在日常生活中经常遇到红绿灯,我们就很好理解红绿灯的例子,就是红灯停,绿灯行。
概述
我现在生成一个线程,这个线程我让它扮演红绿灯,它每过一段时间就变成绿灯,一会儿又变成红灯。然后我再生成3-5个线程作为车。车看见红灯,它就停下来等着,如果说是绿灯,车子就走。所以就涉及到红绿灯这个线程,红绿灯的这个线程就跟车线程之前产生了依赖关系了。就是红绿灯这个线程必须在绿灯的时候才能走,在红灯的时候就立刻停下来。所以他们之间,一个线程会根据另外一个线程的状态产生一些变化。类似这种场景的实现,就引出了一个新的知识点:event,即事件。
就是我们红绿灯这个线程每隔30秒,由绿灯变成红灯,然后红灯会持续20秒,也就是每一次的状态切换,就是一次事件的发生。然后它切换了一次灯的状态。其他的车就会根据这个状态做不同的动作,这个就是因为一个事件导致其他事件的连锁变化。
事件(event)
用法
Python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法wait、clear、set
事件的处理机制
全局定义一个"Flag",如果"Flag"值为False,那么当程序执行event.wait方法时就会阻塞,如果"Flag"值为True,那么event.wait方法时便不再阻塞。
- clear #将"Flag"设置为False
- set #将"Flag"设置为True
event = threading.event() #设置一个事件的全局变量
event.is_set() #判断是否已经设置标志位
#客户端线程等待标志位被设定
event.wait() #没有设置标志位的时候会阻塞,一遇到标志位就不再阻塞
#服务器端线程能够设置或清除
event.set() #设置标志位
event.clear() #清除标志位
如果标志位被设置了,代表绿灯,直接通行。
如果标志位被清除,代表红灯,wait等待变绿灯。
多个线程可以等待相同的事件。
红绿灯例子
说明:通过Event来实现两个或多个线程间的交互,下面的例子,即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯停,绿灯行的规则。
import threading, time
event = threading.Event() # 设置一个事件的全局变量
def lighter():
"红绿灯"
count = 0
event.set() # 先设置绿灯
while True:
if count > 5 and count < 10: # 改成红灯
event.clear() # 清除标志位
print("\033[41mred light is on ....\033[0m")
elif count > 10:
event.set() # 设置标志位,变绿灯
count = 0
else:
print("\033[42mgree light is on ....\033[0m")
time.sleep(1)
count += 1
def car(name):
"车子"
while True:
#判断是否已经设置标志位
if event.is_set(): # 有标志位,代表是绿灯
print("[%s] running ...."%name)
time.sleep(1)
else: # 代表红灯
print("[%s] sees red light ,waiting ...."%name)
event.wait() # 阻塞(没有标志位的时候阻塞,有标志位的时候不阻塞)
print("\033[34;1mgreen light is on , [%s] start going ...\033[0m"%name)
light = threading.Thread(target=lighter, )
light.start()
car1 = threading.Thread(target=car, args=("AUDI",))
car1.start()
car2 = threading.Thread(target=car, args=("ChangChen",))
car2.start()
#运行输出

员工进公司刷卡例子
说明:员工进公司门要刷卡, 我们这里设置一个线程是“门”, 再设置几个线程为“员工”,员工看到门没打开,就刷卡,刷完卡,门开了,员工就可以通过。
#_*_coding:utf-8_*_
import threading
import time
import random
def door():
door_open_time_counter = 0
while True:
if door_swiping_event.is_set():
print("\033[32;1mdoor opening....\033[0m")
door_open_time_counter +=1
else:
print("\033[31;1mdoor closed...., swipe to open.\033[0m")
door_open_time_counter = 0 #清空计时器
door_swiping_event.wait()
if door_open_time_counter > 3:#门开了已经3s了,该关了
door_swiping_event.clear()
time.sleep(0.5)
def staff(n):
print("staff [%s] is comming..." % n )
while True:
if door_swiping_event.is_set():
print("\033[34;1mdoor is opened, passing.....\033[0m")
break
else:
print("staff [%s] sees door got closed, swipping the card....." % n)
print(door_swiping_event.set())
door_swiping_event.set()
print("after set ",door_swiping_event.set())
time.sleep(0.5)
door_swiping_event = threading.Event() #设置事件
door_thread = threading.Thread(target=door)
door_thread.start()
for i in range(5):
p = threading.Thread(target=staff,args=(i,))
time.sleep(random.randrange(3))
p.start()
#运行输出


浙公网安备 33010602011771号