python-- 信号量 Semphore、事件 Event

信号量 Semphore

sem=Semphore(n):n是指初始化一把锁配几把钥匙,一个int型

拿钥匙,锁门 sem.acquire()

还钥匙,开门 sem.release()

信号量机制比锁机制多了一个计数器,这个计数器是用来计录当前剩几把钥匙的。当计数器为0时,表示没有钥匙了,此时acquire()处于阻塞。

对于计数器来说,每acquire一次,计数器内部就减1,release一次,计数器就加1

from multiprocessing import Process, Semaphore

l = Semaphore(3)  # 实例化,传一个int型的值

l.acquire()  # 拿走1把钥匙,锁上门
print(12)
l.acquire()  # 拿走1把钥匙,锁上门
print(34)
l.acquire()  # 拿走1把钥匙,锁上门
print(56)
l.acquire()  # 拿走1把钥匙,锁上门
print(78)

结果:

12
34
56
# 只有三把钥匙,当遇到第四个l.acquire()时就阻塞了

释放锁

from multiprocessing import Process, Semaphore

l = Semaphore(3)  # 实例化,传一个int型的值

l.acquire()  # 拿走1把钥匙,锁上门
print(12)
l.acquire()  # 拿走1把钥匙,锁上门
print(34)
l.acquire()  # 拿走1把钥匙,锁上门
print(56)
l.release()  # 释放钥匙
l.acquire()  # 拿走1把钥匙,锁上门
print(78)

结果

12
34
56
78

案例

from multiprocessing import Process, Semaphore
import time
import random


def func(i, sem):
    sem.acquire()
    print('第%s个人进入小黑屋,拿了钥匙锁上门' % i)
    time.sleep(2)
    print('第%s个人出去小黑屋,还了钥匙打开门' % i)
    sem.release()


if __name__ == '__main__':
    sem = Semaphore(5)  # 初始化了一把锁5把钥匙,也就是说允许5个人同时进入小黑屋
    # 之后其他人必须等待,等有人从小黑屋出来,还了钥匙,才能允许后边的人进入
    for i in range(20):
        p = Process(target=func, args=(i, sem,))
        p.start()

结果:

第0个人进入小黑屋,拿了钥匙锁上门
第1个人进入小黑屋,拿了钥匙锁上门
第2个人进入小黑屋,拿了钥匙锁上门
第3个人进入小黑屋,拿了钥匙锁上门
第4个人进入小黑屋,拿了钥匙锁上门
第0个人出去小黑屋,还了钥匙打开门
第1个人出去小黑屋,还了钥匙打开门
第5个人进入小黑屋,拿了钥匙锁上门
第6个人进入小黑屋,拿了钥匙锁上门
第2个人出去小黑屋,还了钥匙打开门第3个人出去小黑屋,还了钥匙打开门

第7个人进入小黑屋,拿了钥匙锁上门
第8个人进入小黑屋,拿了钥匙锁上门
第4个人出去小黑屋,还了钥匙打开门
第9个人进入小黑屋,拿了钥匙锁上门
第5个人出去小黑屋,还了钥匙打开门
第6个人出去小黑屋,还了钥匙打开门
第10个人进入小黑屋,拿了钥匙锁上门
第11个人进入小黑屋,拿了钥匙锁上门
第7个人出去小黑屋,还了钥匙打开门
第8个人出去小黑屋,还了钥匙打开门
第9个人出去小黑屋,还了钥匙打开门
第12个人进入小黑屋,拿了钥匙锁上门
第13个人进入小黑屋,拿了钥匙锁上门
第14个人进入小黑屋,拿了钥匙锁上门
第10个人出去小黑屋,还了钥匙打开门第11个人出去小黑屋,还了钥匙打开门

第14个人出去小黑屋,还了钥匙打开门第12个人出去小黑屋,还了钥匙打开门

第13个人出去小黑屋,还了钥匙打开门
第17个人进入小黑屋,拿了钥匙锁上门
第18个人进入小黑屋,拿了钥匙锁上门第15个人进入小黑屋,拿了钥匙锁上门

第19个人进入小黑屋,拿了钥匙锁上门第16个人进入小黑屋,拿了钥匙锁上门

第18个人出去小黑屋,还了钥匙打开门第15个人出去小黑屋,还了钥匙打开门第17个人出去小黑屋,还了钥匙打开门


第19个人出去小黑屋,还了钥匙打开门
第16个人出去小黑屋,还了钥匙打开门

事件 Event

e = Event()
e.set()
e.clear()
e.wait()
e.is_set()
# 事件是通过is_set()的bool值,去标识e.wait() 的阻塞状态
# 当is_set()的bool值为False时,e.wait()是阻塞状态
# 当is_set()的bool值为True时,e.wait()是非阻塞状态
# 当使用set()时,是把is_set的bool变为True
# 当使用clear()时,是把is_set的bool变为False

红绿灯案例

from multiprocessing import Process, Event
import time


def lighter(l):
    count = 0
    l.set()  # 先设置绿灯
    while True:
        if count > 5 and count < 10:
            l.clear()  # 把标志位清了,改为红 灯
            print('\033[41;1m  red light  ...\033[0m')
        elif count > 10:
            l.set()  # 变绿灯
            count = 0
        else:
            print('\033[42;1m green light...\033[0m')
        time.sleep(1)
        count += 1


def car(name, l):
    while True:
        if l.is_set():  # 判断标志位是否存在
            print('[%s] runing' % name)
            time.sleep(1)
        else:
            print('[%s] sees red light,waiting...' % name)
            l.wait()  # 等待标志位设定
            print('\033[34;1m[%s] green light is on,start going...\033[0m' % name)


if __name__ == '__main__':
    l = Event()
    light = Process(target=lighter, args=(l,))
    light.start()
    car1 = Process(target=car, args=('BMW', l))
    car1.start()

 

posted @ 2021-07-30 22:56  邹邹很busy。  阅读(101)  评论(0编辑  收藏  举报