并发编程 - 进程 - 1.队列的使用/2.生产者消费者模型/3.JoinableQueue

1.队列的使用:
  队列引用的前提: 多个进程对同一块共享数据的修改:要从硬盘读文件,慢,还要考虑上锁:
   所以就出现了 队列 和 管道 都在内存中(快); 队列 = 管道 + 上锁

  用队列的目的:
  进程间通信(IPC),队列可以放任意类型的数据,应该放小东西,
  q = Queue(3)
  get put full empty

  队列作用:
   多个进程之间通信使用的,一个进程将数据放到队列里面,另外一个进程从队列里面取走数据,干的是进程之间通信的活
 1 from multiprocessing import Queue
 2 
 3 q = Queue(3)
 4 q.put('hello')
 5 q.put({'a':1})
 6 q.put([3,3,3])
 7 
 8 print(q.full())  # 查看队列是否满了
 9 # q.put(2)  # 这里会卡住,直到队列中被取走一个
10 
11 print(q.get())
12 print(q.get())
13 q.put(2)
14 print(q.get())
15 print(q.get())
16 print(q.empty())  # 查看队列是否为空
17 print(q.get())  # 取完数据后,再取,就卡住了

2.生产者消费者模型:
  生产者:
   生产者指的是生产数据的任务
  消费者:
   消费者指的是处理数据的任务

  生产者与消费者模型:
   生产者与消费者之间引入一个容器(队列):
  生产者《---》队列《---》消费者

  好处:程序解开耦合,生产者与消费者不直接通信
   平衡了生产者与消费者的速度差

   生产者:一个进程
  消费者:一个进程
  进程间通信:队列(IPC)

  如果生产者,消费者,队列组件都在一台机器上:
   集中式:稳定性差,性能问题差

  分布在多台机器上:
   Rabbitmq 用它来实现生产者,消费者模型
 1 from multiprocessing import Process,Queue
 2 import time
 3 
 4 def producer(q):
 5     for i in range(10):
 6         res = '包子%s'%i
 7         time.sleep(0.5)
 8         print('生产者生产了%s'%res)
 9 
10         q.put(res)
11 
12 def consumer(q):
13     while True:
14         res = q.get()
15         if not res:break
16         time.sleep(1)
17         print('消费者吃了%s'%res)
18 
19 if __name__ == "__main__":
20     # 容器
21     q = Queue()
22 
23     # 生产者们
24     p1 = Process(target=producer,args=(q,))
25     p2 = Process(target=producer, args=(q,))
26     p3 = Process(target=producer, args=(q,))
27 
28     # 消费者们
29     c1 = Process(target=consumer,args=(q,))
30     c2 = Process(target=consumer,args=(q,))
31 
32     p1.start()
33     p2.start()
34     p3.start()
35     c1.start()
36     c2.start()
37 
38     p1.join()
39     p2.join()
40     p3.join()
41     q.put(None)  # 两个消费者,所以放两个None
42     q.put(None)
43 
44     print('')

3.JoinableQueue:
q = JoinableQueue()
q.join()
q.task_done()
 1 from multiprocessing import Process,Queue,JoinableQueue
 2 import time
 3 
 4 def producer(q):
 5     for i in range(2):
 6         res = '包子%s'%i
 7         time.sleep(0.5)
 8         print('生产者生产了%s'%res)
 9 
10         q.put(res)
11     q.join()  # 等待队列为空
12 
13 def consumer(q):
14     while True:
15         res = q.get()
16         if not res:break
17         time.sleep(1)
18         print('消费者吃了%s'%res)
19         q.task_done()  # 消费者发信号,任务结束
20 
21 if __name__ == "__main__":
22     # 容器
23     q = JoinableQueue()
24 
25     # 生产者们
26     p1 = Process(target=producer,args=(q,))
27     p2 = Process(target=producer, args=(q,))
28     p3 = Process(target=producer, args=(q,))
29 
30     # 消费者们
31     c1 = Process(target=consumer,args=(q,))
32     c2 = Process(target=consumer,args=(q,))
33     c1.daemon = True  # 消费者没有存在的必要,设为守护进程
34     c2.daemon = True
35 
36     p1.start()
37     p2.start()
38     p3.start()
39     c1.start()
40     c2.start()
41 
42     p1.join()
43     p2.join()
44     p3.join()
45 
46 
47     print('')

 



posted @ 2018-04-02 21:08  Alice的小屋  阅读(144)  评论(0编辑  收藏  举报