1. 信号量
信号量本质也是锁,只不过一把锁可以有很多钥匙(自己设置),决定同一时间可以有多个进程同时操作,其他进程会一直等待(阻塞)知道拿到钥匙的进程释放钥匙;
from multiprocessing import Process,Semaphore sem=Semaphore(4) # 设置四把钥匙,表明可以同时开四个进程 sem.acquire() # 需要钥匙 print("第一个进程拿到钥匙,进来") sem.acquire() print("第二个进程拿到钥匙,可以进来") sem.acquire() print("第三个进程拿到钥匙,可以进来") sem.acquire() print("第四个进程拿到钥匙,可以进来") # sem.acquire() # 发生阻塞,因为四把钥匙已经被四个进程占用了 # # print("第五个进程会一直等待,知道有进程释放钥匙")
运行结果:
当占有钥匙的进程执行完毕之后,其他进程就会有机会拿到释放的钥匙,执行相应的操作:
from multiprocessing import Process,Semaphore sem=Semaphore(4) # 设置四把钥匙,表明可以同时开四个进程 sem.acquire() # 需要钥匙 print("第一个进程拿到钥匙,进来") sem.acquire() print("第二个进程拿到钥匙,可以进来") sem.acquire() print("第三个进程拿到钥匙,可以进来") sem.acquire() print("第四个进程拿到钥匙,可以进来") sem.release() # 释放一个钥匙 print("释放一把钥匙") sem.acquire() # 发生阻塞,因为四把钥匙已经被四个进程占用了 print("第五个进程拿到钥匙了,可以执行")
运行结果:
2. 迷你唱吧
使用multiprocessing模块的Semophore类,实现迷你唱吧(20个人只有四个人可以进去唱歌)所以可以开20个进程,但是设置四把钥匙,也就是同一时间只有四个人可以进去唱吧:
from multiprocessing import Process,Semaphore import time import random def sing(i,sem): sem.acquire() # 拿到一把钥匙,才可以执行相应的操作(但是只有四把钥匙,说明同一时间也只有四个进程执行sing()) print("%s:在唱歌"%i) time.sleep(random.randint(1,10)) # 拿到钥匙的进程(代表进入迷你唱吧的人)唱歌时间为1-10秒,模拟 print("%s离开唱吧"%i) sem.release() # 该进程释放钥匙,代表进入唱吧的人离开唱吧,在外面等候的进程有机会拿到钥匙,进入唱吧唱歌 if __name__=="__main__": sem=Semaphore(4) # 锁设置四把钥匙,同一时间只有四个进程可以拿到钥匙执行任务,模拟只有四个人进入唱吧唱歌 for i in range(20): p=Process(target=sing,args=(i,sem)) p.start()
运行结果: