线程中的samaphore信号量及event事件 a client thread can wait for the flag to be set a server thread can set or reset it

线程中的samaphore信号量及event事件
a client thread can wait for the flag to be set
a server thread can set or reset it

一、信号量
samaphore: 在程序中意思为同时允许几个线程运行,比如我们去水上乐园的滑梯玩时,有四个滑梯,每一个滑梯上当没有人在中间玩滑下去时才允许上人,四个滑梯1,2,3,4,同时最多四个人,当少有一个滑下去完成了。后面补上,就是后面的人必须等前面有人完成了才能补上去。 - 互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据。常用在数据库、连接池等地方
import threading,time
 
def run(n):
    semaphore.acquire()
    time.sleep(1)
    print("run the thread: %s
" %n)
    semaphore.release()
 
if __name__ == '__main__':
 
    num= 0
    samaphore = threading.BoundedSamaphore(5)  #最多允许5个线程同时运行
    for i in range(20):
        t = threading.Thread(target=run,args=(i,))
        t.start()
 
while threading.active_count() != 1:
    pass #print threading.active_count()
else:
    print('----all threads done---')
    print(num)
二、事件
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.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.
Any number of threads may wait for the same event.

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

import threading,time
import random
def light():
    if not event.isSet():
        event.set() #wait就不阻塞 #绿灯状态
    count = 0
    while True:
        if count < 10:
            print(' 33[42;1m--green light on--- 33[0m')
        elif count <13:
            print(' 33[43;1m--yellow light on--- 33[0m')
        elif count <20:
            if event.isSet():
                event.clear()
            print(' 33[41;1m--red light on--- 33[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()

event = threading.Event() 申请一个事件实例。 event.set() 设置标记, event.isSet() 如果标记设置返回True, event.wait()检查标记是否设置,如果没设置阻塞程序,直到标记被设置, event.clear()清空标记