进程-队列,管道,数据共享,进程池
1 import time 2 import random 3 from multiprocessing import JoinableQueue,Process 4 # join 阻塞 5 def consumer(q,name): 6 while True: 7 food = q.get() 8 print('%s 吃了 %s'%(name,food)) 9 time.sleep(random.random()) 10 q.task_done() 11 12 def producer(q,name,food,n=10): 13 for i in range(n): 14 time.sleep(random.random()) 15 fd = food+str(i) 16 print('%s 生产了 %s'%(name,fd)) 17 q.put(fd) 18 q.join() 19 20 if __name__ == '__main__': 21 q = JoinableQueue() 22 c1 = Process(target=consumer,args=(q,'alex')) 23 c1.daemon = True 24 c1.start() 25 c2 = Process(target=consumer, args=(q, 'alex')) 26 c2.daemon = True 27 c2.start() 28 p1 = Process(target=producer,args=(q,'太白','泔水')) 29 p1.start() 30 p2 = Process(target=producer, args=(q, 'egon', '鱼刺')) 31 p2.start() 32 p1.join() 33 p2.join()
只有multiprocessing中的队列 才能帮助你 实现 IPC
永远不可能出现数据不安全的情况,多个进程不会同时取走同一个数据
提供给你的方法
put
get
put_nowait
get_nowait
empty - 在多进程内不可靠
full - 在多进程内不可靠
qsize - 在多进程内不可靠
由于先进先出的特点+进程通信的功能+数据进程安全,经常用它来完成进程之间的通信
生产者消费者模型
生产者和消费者的效率平衡的问题
内存的控制 - 队列的长度限制
让消费者自动停下来
JoinableQueue
在消费数据的时候 task_done
在生产端\主进程 join
二 管道
队列就是基于管道实现的
队列 数据安全的
管道 数据不安全的
队列 = 管道 + 锁
1 from multiprocessing import Pipe 2 left,right = Pipe() 3 left.send('aaa') 4 print(right.recv()) 5 6 from multiprocessing import Pipe,Process 7 def consumer(left,right): 8 left.close() 9 while True: 10 try: 11 print(right.recv()) 12 except EOFError: 13 break 14 15 if __name__ == '__main__': 16 left,right = Pipe() 17 p = Process(target=consumer,args=(left,right)) 18 p.start() 19 right.close() 20 for i in range(10): 21 left.send('hello') 22 left.close()
EOF异常的触发
在这一个进程中 如果不在用这个端点了,应该close
这一在recv的时候,如果其他端点都被关闭了,就能够知道不会在有新的消息传进来
此时就不会在这里阻塞等待,而是抛出一个EOFError
* close并不是关闭了整个管道,而是修改了操作系统对管道端点的引用计数的处理
三.数据共享
1 from multiprocessing import Manager,Process,Lock 2 def work(d,lock): 3 with lock: 4 d['count']-=1 5 6 if __name__ == '__main__': 7 lock = Lock() 8 m = Manager() #开启共享 9 dic=m.dict({'count':100}) 10 p_l=[] 11 for i in range(100): 12 p=Process(target=work,args=(dic,lock)) 13 p_l.append(p) 14 p.start() 15 for p in p_l: 16 p.join() 17 print(dic)
四.进程池
开启进程慢
几个CPU就能同时运行几个进程 进程的个数不是无限开启的
100个任务
进程池
如果必须用多个进程
且是高计算型 没有IO 型的程序
希望并行 最充分的使用CPU
1 import os 2 import time 3 from multiprocessing import Pool 4 def func(i): 5 time.sleep(0.1) 6 print(os.getpid(),i) 7 8 if __name__ == '__main__': 9 p = Pool(5) 10 for i in range(20): 11 p.apply_async(func,args=(i,)) 12 p.close() 13 p.join()

浙公网安备 33010602011771号