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()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)