event(红绿灯例子)

一、概述

  我们日常生活中经常遇到红绿灯,我们就很好理解红绿灯的例子,就是红灯停,绿灯行。

  我现在生成一个线程,这个线程我让它扮演红绿灯,它每过一段时间就变成绿灯,又过一段时间变成红灯,又变成黄灯。然后我再生成3-5个线程作为车。车看见红灯,它就停下来等着,如果说是绿灯,车子就走。所以就涉及到红灯这个线程,红绿灯的这个线程就跟车线程之前产生了依赖了。就是红绿灯这个线程必须在绿灯的时候才能走,在红灯的时候就立刻停下来。所以互相之前,一个线程会根据另外一个线程的状态产生一些变化。类似这种场景的实现,就讲到了一个知识点:event,即事件。

  就是我们红绿灯这个线程每隔30秒,由绿灯变成红灯,然后红灯会持续20秒,也就是没一次的状态切换,就是一次事件的发生。然后它切换了一次灯的状态。其他的车就会根据这个状态做不同的动作,这个就是因为一个事件导致其他事件的连锁变化。

 二、事件(event)

2.1、英文说明

An event is a simple synchronization object; 

一个事件是一个简单的同步对象(线程之前进行同步的)

the event represents an internal flag, and threads can wait for the flag to be set, or set or clear the flag themselves.
这个事情是内部的一个标志,线程可等到标志位被设置,或者设置,或者清除这些标志位


event = threading.Event()   #设置一个事件的全局变量


event.is_set()  #判断是否已经设置标志位。


# a client thread can wait for the flag to be set  #等待标志位被设定
event.wait()   #没有设置标志位的时候会阻塞,一遇到标志位就不会阻塞

# a server thread can set or reset it
event.set()   #设置标志位
event.clear()   #清除标志位


If the flag is set, the wait method doesn’t do anything.

如果标志位设置了,代表着绿灯,直接通行。
If the flag is cleared, wait will block until it becomes set again.

如果标志位被清空,代表红灯,wait等待变绿灯。
Any number of threads may wait for the same event.

多个线程可以同时等待一个相同的时间。

2.2、红绿灯例子

说明:定义一个红绿灯的函数 ->定义车子的函数->启动两个线程

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("{0} running ....".format(name))
            time.sleep(1)
        else:   #代表红灯
            print("{0} sees red light ,waiting ....".format(name))
            event.wait()   #阻塞
            print("\033[32mgreen light is on , start going ...\033[0m")
 
light = threading.Thread(target=lighter,)
light.start()
 
car1 = threading.Thread(target=car,args=("car1",))
car1.start()

 

2.3、红绿灯另外一个例子

说明:通过Event来实现两个或多个线程间的交互,下面是一个红绿灯的例子,即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯停,绿灯行的规则。

import threading,time
import random
def light():
    if not event.isSet():
        event.set() #wait就不阻塞 #绿灯状态
    count = 0
    while True:
        if count < 10:
            print('\033[42;1m--green light on---\033[0m')
        elif count <13:
            print('\033[43;1m--yellow light on---\033[0m')
        elif count <20:
            if event.isSet():
                event.clear()
            print('\033[41;1m--red light on---\033[0m')
        else:
            count = 0
            event.set() #打开绿灯
        time.sleep(1)
        count +=1
def car(n):
    while 1:
        time.sleep(random.randrange(10))
        if  event.isSet(): #绿灯
            print("car [%s] is running.." % n)
        else:
            print("car [%s] is waiting for the red light.." %n)
if __name__ == '__main__':
    event = threading.Event()
    Light = threading.Thread(target=light)
    Light.start()
    for i in range(3):
        t = threading.Thread(target=car,args=(i,))
        t.start()

 

2.4、员工进公司刷卡

说明:员工进公司门要刷卡, 我们这里设置一个线程是“门”, 再设置几个线程为“员工”,员工看到门没打开,就刷卡,刷完卡,门开了,员工就可以通过。

 1 import threading
 2 import time
 3 import random
 4 
 5 def door():
 6     door_open_time_counter = 0
 7     while True:
 8         if door_swiping_event.is_set():
 9             print("\033[32;1mdoor opening....\033[0m")
10             door_open_time_counter +=1
11 
12         else:
13             print("\033[31;1mdoor closed...., swipe to open.\033[0m")
14             door_open_time_counter = 0 #清空计时器
15             door_swiping_event.wait()
16 
17 
18         if door_open_time_counter > 3:#门开了已经3s了,该关了
19             door_swiping_event.clear()
20 
21         time.sleep(0.5)
22 
23 
24 def staff(n):
25 
26     print("staff [%s] is comming..." % n )
27     while True:
28         if door_swiping_event.is_set():
29             print("\033[34;1mdoor is opened, passing.....\033[0m")
30             break
31         else:
32             print("staff [%s] sees door got closed, swipping the card....." % n)
33             print(door_swiping_event.set())
34             door_swiping_event.set()
35             print("after set ",door_swiping_event.set())
36         time.sleep(0.5)
37 door_swiping_event  = threading.Event() #设置事件
38 
39 
40 door_thread = threading.Thread(target=door)
41 door_thread.start()
42 
43 
44 
45 for i in range(5):
46     p = threading.Thread(target=staff,args=(i,))
47     time.sleep(random.randrange(3))
48     p.start()
49 
50 员工刷卡
员工刷卡

 

posted @ 2017-10-14 10:36  人生是一场修行  阅读(196)  评论(0编辑  收藏  举报