提前设定好,一个房间只有4个床(计数器现在为4),那么同时只能四个人进来,谁先来的谁先占一个床(acquire,计数器减1),4个床满了之后(计数器为0了),第五个人就要等着,等其中一个人出来(release,计数器加1),他就去占用那个床了。
互斥锁同时只允许一个线程更改数据,而信号量Semaphore是同时允许一定数量的线程更改数据 。 假设商场里有4个迷你唱吧,所以同时可以进去4个人,如果来了第五个人就要在外面等待,等到有人出来才能再进去玩。 实现: 信号量同步基于内部计数器,每调用一次acquire(),计数器减1;每调用一次release(),计数器加1.当计数器为0时,acquire()调用被阻塞。这是迪科斯彻(Dijkstra)信号量概念P()和V()的Python实现。信号量同步机制适用于访问像服务器这样的有限资源。 信号量与进程池的概念很像,但是要区分开,信号量涉及到加锁的概念
# -*- coding: utf-8 -*- import os import time from multiprocessing import Process def go_ktv(i): print("user%s正在....ktv.子进程(%s)" % (i, os.getpid())) time.sleep(2) if __name__ == '__main__': '''开启20个进程,操作系统可以调度4个cpu去执行,进程的调用比线程的开销大些''' start_time = time.time() p_lst = [] for i in range(20): p = Process(target=go_ktv, args=(i,)) p.start() p_lst.append(p) [pp.join() for pp in p_lst] print("运行时间: %s.主进程<%s>" % ((time.time() - start_time), os.getpid())) # user0正在....ktv.子进程(5496) # user1正在....ktv.子进程(6996) # user3正在....ktv.子进程(6328) # user2正在....ktv.子进程(1064) # user4正在....ktv.子进程(4844) # user7正在....ktv.子进程(7804) # user5正在....ktv.子进程(7688) # user8正在....ktv.子进程(7136) # user6正在....ktv.子进程(7824) # user9正在....ktv.子进程(7812) # user10正在....ktv.子进程(8148) # user11正在....ktv.子进程(2556) # user13正在....ktv.子进程(4744) # user15正在....ktv.子进程(6232) # user14正在....ktv.子进程(5168) # user16正在....ktv.子进程(6444) # user12正在....ktv.子进程(2616) # user17正在....ktv.子进程(5188) # user18正在....ktv.子进程(8088) # user19正在....ktv.子进程(7224) # 运行时间: 3.2611865997314453.主进程<6936>
# -*- coding: utf-8 -*- import os import time from multiprocessing import Pool def go_ktv(i): print("user%s正在....ktv.子进程(%s)" % (i, os.getpid())) time.sleep(2) if __name__ == '__main__': '''创建进程池,进程的容量默认是4,
如果总进程的数量超过4,就会自动排队等待,一次可执行4个进程,进程池内的进程结束一个,就会自动进来一个新的进程,重用原来的进程号,节省开销''' start_time = time.time() pool = Pool() p_lst = [] for i in range(20): pool.apply_async(go_ktv, args=(i,)) pool.close() pool.join() print("运行时间: %s.主进程<%s>" % ((time.time() - start_time), os.getpid())) # user0正在....ktv.子进程(7396) # user1正在....ktv.子进程(1760) # user2正在....ktv.子进程(8000) # user3正在....ktv.子进程(4120) # user4正在....ktv.子进程(7396) # user5正在....ktv.子进程(1760) # user6正在....ktv.子进程(8000) # user7正在....ktv.子进程(4120) # user8正在....ktv.子进程(7396) # user9正在....ktv.子进程(1760) # user10正在....ktv.子进程(8000) # user11正在....ktv.子进程(4120) # user12正在....ktv.子进程(7396) # user13正在....ktv.子进程(1760) # user14正在....ktv.子进程(8000) # user15正在....ktv.子进程(4120) # user16正在....ktv.子进程(7396) # user17正在....ktv.子进程(1760) # user18正在....ktv.子进程(8000) # user19正在....ktv.子进程(4120) # 运行时间: 10.851620435714722.主进程<7428>
# -*- coding: utf-8 -*- import os import time from multiprocessing import Process, Semaphore def go_ktv(i, sem): with sem: print("user%s正在....ktv.子进程(%s)" % (i, os.getpid())) time.sleep(2) if __name__ == '__main__': '''开启20个进程,一次可执行4(信号量容量)个进程,相当于添加另一个互斥锁''' start_time = time.time() sem = Semaphore(4) p_lst = [] for i in range(20): p = Process(target=go_ktv, args=(i, sem)) p.start() p_lst.append(p) [pp.join() for pp in p_lst] print("运行时间: %s.主进程<%s>" % ((time.time() - start_time), os.getpid())) # user0正在....ktv.子进程(3660) # user1正在....ktv.子进程(7188) # user3正在....ktv.子进程(7268) # user2正在....ktv.子进程(7568) # user5正在....ktv.子进程(2896) # user6正在....ktv.子进程(2852) # user7正在....ktv.子进程(376) # user4正在....ktv.子进程(7532) # user9正在....ktv.子进程(8188) # user10正在....ktv.子进程(1444) # user12正在....ktv.子进程(6304) # user11正在....ktv.子进程(6776) # user14正在....ktv.子进程(6992) # user13正在....ktv.子进程(7248) # user8正在....ktv.子进程(6820) # user17正在....ktv.子进程(6308) # user15正在....ktv.子进程(8020) # user18正在....ktv.子进程(4312) # user16正在....ktv.子进程(2724) # user19正在....ktv.子进程(7516) # 运行时间: 10.443597078323364.主进程<2560>