信号量 Semphore sem=Semphore(n):n是指初始化一把锁配几把钥匙,一个int型 拿钥匙,锁门 sem.acquire() 还钥匙,开门 sem.release() 信号量机制比锁机制多了一个计数器,这个计数器是用来计录当
信号量 Semphore
sem=Semphore(n):n是指初始化一把锁配几把钥匙,一个int型
拿钥匙,锁门 sem.acquire()
还钥匙,开门 sem.release()
信号量机制比锁机制多了一个计数器,这个计数器是用来计录当前剩几把钥匙的。当计数器为0时,表示没有钥匙了,此时acquire()处于阻塞。
对于计数器来说,每acquire一次,计数器内部就减1,release一次,计数器就加1
from multiprocessing import Process, Semaphorel = Semaphore(3) # 实例化,传一个int型的值
l.acquire() # 拿走1把钥匙,锁上门
print(12)
l.acquire() # 拿走1把钥匙,锁上门
print(34)
l.acquire() # 拿走1把钥匙,锁上门
print(56)
l.acquire() # 拿走1把钥匙,锁上门
print(78)
结果:
1234
56
# 只有三把钥匙,当遇到第四个l.acquire()时就阻塞了
释放锁
from multiprocessing import Process, Semaphorel = 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)
结果
1234
56
78
案例
from multiprocessing import Process, Semaphoreimport 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, Eventimport 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()