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()
#运行输出

 

posted @ 2017-12-07 15:01  Mr.hu  阅读(130)  评论(0编辑  收藏  举报