# 进程锁的作用是同一时间只允许一个进程访问被锁的代码 # 信号量的作用是统一时间允许指定个数进程访问代码 # from multiprocessing import Process # import time # import random # # def func(i): # print("%s开始执行代码"%(i),time.time()) # time.sleep(random.randint(1,5)) # print("%s执行结束"%(i),time.time()) # # # 有20个进程要执行func # if __name__ == '__main__': # for i in range(1,21): # p = Process(target=func,args=(i,)) # p.start() ''' 1开始执行代码 1555142395.3926342 2开始执行代码 1555142395.3946288 3开始执行代码 1555142395.445492 4开始执行代码 1555142395.4544683 5开始执行代码 1555142395.5212898 6开始执行代码 1555142395.5881112 7开始执行代码 1555142395.6200256 8开始执行代码 1555142395.64097 9开始执行代码 1555142395.6938314 10开始执行代码 1555142395.7566607 11开始执行代码 1555142395.7875812 12开始执行代码 1555142395.843428 13开始执行代码 1555142395.8703563 14开始执行代码 1555142395.9112463 15开始执行代码 1555142395.9661005 16开始执行代码 1555142396.0109806 17开始执行代码 1555142396.0558605 18开始执行代码 1555142396.0718174 19开始执行代码 1555142396.1117103 20开始执行代码 1555142396.1695824 17执行结束 1555142397.0563135 18执行结束 1555142397.0723288 3执行结束 1555142397.445812 4执行结束 1555142397.4548035 6执行结束 1555142397.5884788 9执行结束 1555142397.694322 11执行结束 1555142397.787952 14执行结束 1555142397.9116335 15执行结束 1555142397.9664843 16执行结束 1555142398.0114963 10执行结束 1555142398.75727 12执行结束 1555142398.8438897 13执行结束 1555142398.8708198 19执行结束 1555142399.112128 1执行结束 1555142399.393596 5执行结束 1555142399.5213497 7执行结束 1555142399.620567 2执行结束 1555142400.39559 8执行结束 1555142400.6415663 20执行结束 1555142401.1699862 ''' # 20个进程几乎同时开始了执行代码 # 使用信号量控制指定数量进程可以执行代码 # from multiprocessing import Process # from multiprocessing import Semaphore # import time # import random # # def func(i,sem): # sem.acquire() # print("%s开始执行代码"%(i),time.time()) # time.sleep(random.randint(1,5)) # print("%s执行结束"%(i),time.time()) # sem.release() # # 有20个进程要执行func # if __name__ == '__main__': # sem = Semaphore(4) # for i in range(1,21): # p = Process(target=func,args=(i,sem)) # p.start() ''' 1开始执行代码 1555142606.4910986 3开始执行代码 1555142606.5210192 2开始执行代码 1555142606.5494523 4开始执行代码 1555142606.5783749 1执行结束 1555142607.4916732 5开始执行代码 1555142607.4916732 3执行结束 1555142607.521539 6开始执行代码 1555142607.521539 6执行结束 1555142608.522116 8开始执行代码 1555142608.522116 2执行结束 1555142608.5499928 7开始执行代码 1555142608.5499928 5执行结束 1555142610.4926128 9开始执行代码 1555142610.4926128 7执行结束 1555142610.5504608 10开始执行代码 1555142610.5504608 4执行结束 1555142610.5783856 11开始执行代码 1555142610.5783856 8执行结束 1555142611.5229352 12开始执行代码 1555142611.5229352 12执行结束 1555142613.523161 13开始执行代码 1555142613.523161 10执行结束 1555142613.5509596 14开始执行代码 1555142613.5509596 11执行结束 1555142614.5784695 16开始执行代码 1555142614.5784695 9执行结束 1555142615.4931543 15开始执行代码 1555142615.4931543 14执行结束 1555142617.5513644 17开始执行代码 1555142617.5513644 13执行结束 1555142618.523744 18开始执行代码 1555142618.523744 17执行结束 1555142618.551792 19开始执行代码 1555142618.551792 15执行结束 1555142619.4933243 20开始执行代码 1555142619.4933243 16执行结束 1555142619.5790558 20执行结束 1555142621.494176 18执行结束 1555142622.5248418 19执行结束 1555142623.55239 ''' # 可以看到,同时只有4个进程在运行,只有有进程退出(sem.release)后,其它进程才可以运行起来 # 事件--使用事件的set,clear配合wait方法控制进程的阻塞 # 红绿灯模型 # from multiprocessing import Process # from multiprocessing import Event # import random # import time # # def cars(event,n): # while True: # if event.is_set(): # print("car%s通过"%(n)) # break # else: # print("car%s等待绿灯"%(n)) # event.wait() # # def light(event): # while True: # print("绿灯亮") # event.set() # time.sleep(3) # event.clear() # print("红灯亮") # time.sleep(2) # event.set() # # if __name__ == '__main__': # event = Event() # p_light = Process(target=light,args=(event,)) # p_light.start() # for i in range(1,21): # p_car = Process(target=cars,args=(event,i)) # p_car.start() # time.sleep(1) ''' 绿灯亮 car1通过 car3通过 car2通过 红灯亮 car4等待绿灯 car5等待绿灯 绿灯亮 car4通过 car5通过 car6通过 car7通过 car8通过 红灯亮 car9等待绿灯 car10等待绿灯 绿灯亮 car9通过 car10通过 car11通过 car12通过 car13通过 红灯亮 car14等待绿灯 car15等待绿灯 绿灯亮 car14通过 car15通过 car16通过 car17通过 car18通过 红灯亮 car19等待绿灯 car20等待绿灯 绿灯亮 car19通过 car20通过 红灯亮 绿灯亮 红灯亮 绿灯亮 ''' # 进程间通信(IPC)-Queue(队列) # from multiprocessing import Process # from multiprocessing import Queue # # def func(q): # q.put(1) # # if __name__ == '__main__': # q = Queue() # p = Process(target=func,args=(q,)) # p.start() # print(q.get()) # 输出了1 # 生产者消费者模型 # from multiprocessing import Process # from multiprocessing import Queue # import random # import time # # def producer(q,i): # time.sleep(random.random()) # q.put("第%s条消息"%(i)) # print("生产了第%s条消息"%(i)) # # def consumer(q,i): # time.sleep(random.random()) # ret = q.get() + "被消费了" # print(ret) # # if __name__ == '__main__': # q = Queue() # for i in range(20): # p = Process(target=producer,args=(q,i)) # p.start() # for i in range(20): # p = Process(target=consumer,args=(q,i)) # p.start() ''' 生产了第3条消息 生产了第2条消息 生产了第4条消息 生产了第6条消息 生产了第7条消息 生产了第8条消息 生产了第1条消息 生产了第13条消息 生产了第0条消息 生产了第11条消息 生产了第10条消息 生产了第16条消息 生产了第5条消息 生产了第12条消息 生产了第18条消息 生产了第9条消息 生产了第19条消息 生产了第15条消息 第3条消息被消费了 第2条消息被消费了 生产了第14条消息 第4条消息被消费了 第6条消息被消费了 生产了第17条消息 第7条消息被消费了 第8条消息被消费了 第1条消息被消费了 第13条消息被消费了 第0条消息被消费了 第11条消息被消费了 第10条消息被消费了 第16条消息被消费了 第5条消息被消费了 第12条消息被消费了 第18条消息被消费了 第9条消息被消费了 第19条消息被消费了 第15条消息被消费了 第14条消息被消费了 第17条消息被消费了 ''' # 生产者生产的消息与要消费者要消费的消息对等,则没有问题,如果生产者生产的数据少于消费者要消费的数据,则整个程序会进入阻塞状态 # 如果消费者要消费的消息少于生产者生产的数据少于生产者生产的,则还有消息未被消费完,根本原因在于消费者无法感知生产者的结束 # 手动发送结束信号解决生产者消费者问题 # from multiprocessing import Process # from multiprocessing import Queue # import time # import random # # def producer(q,n): # time.sleep(random.random()) # q.put(n) # print("生产者生产了第%d条消息"%(n)) # def consumer(q): # while True: # time.sleep(random.random()) # ret = q.get() # if ret: # print("消费了第%d条消息"%(ret)) # else:break # if __name__ == '__main__': # q = Queue() # pro_lst = [] # for i in range(1,21): # pro = Process(target=producer,args=(q,i)) # pro.start() # pro_lst.append(pro) # con = Process(target=consumer,args=(q,)) # con.start() # for p in pro_lst:p.join() # q.put(None) # 手动发送结束信息的方式有多少个消费者就要发送多少个结束信息 # 使用JoinableQueue解决生产者消费者问题 # from multiprocessing import Process # from multiprocessing import JoinableQueue # import time,random # # def producer(q,n): # for i in range(n): # time.sleep(random.random()) # q.put(n) # print("生产了第%d条消息"%(i)) # q.join() # 等待队列中的数据被全部消费完才结束(即感知计数器吉减为0了) # def consumer(q): # while True: # time.sleep(random.random()) # ret = q.get() # print("消费了第%d条消息"%(ret)) # q.task_done() # 消费一条消息计数器减1 # # if __name__ == '__main__': # q = JoinableQueue() # 可以认为内部维持着一个计数器,每放入一个数据加1 # p = Process(target=producer,args=(q,10)) # c = Process(target=consumer,args=(q,)) # c.daemon = True # 消费者随着主进程代码结束而结束 # p.start() # c.start() # p.join() # 等待生产者进程结束 # 整个流程为:生产者进程依赖于消费者取完队列中的消息而结束,消费者进程依赖于主进程代码结束而结束
Python之进程信号量,事件,进程间通信与生产者消费者模型
最新推荐文章于 2022-03-31 20:30:38 发布