Python全栈_生产者消费者模型、管道、数据共享、进程池

1、生产者消费者模型

   生产者 —— 生产数据的人

  消费者 —— 消费数据的人

  生产者消费者模型:供销数据不平衡的现象。

 1 import time
 2 import random
 3 from multiprocessing import Process, Queue
 4 
 5 def consumer(q):
 6     while True:
 7         obj = q.get()
 8         print(f'消费了一个数据{obj}')
 9         time.sleep(random.randint(1, 3))
10 
11 if __name__ == "__main__":
12     q = Queue()
13     Process(target=consumer, args=(q,)).start()
14     for i in range(10):
15         time.sleep(random.randint(1, 5))
16         q.put(f"food{i}")
17         print(f'生产了一个数据food{i}')
生产者消费者速度不一致
D:\Python36\python.exe E:/Python/草稿纸.py
生产了一个数据food0
消费了一个数据food0
生产了一个数据food1
消费了一个数据food1
生产了一个数据food2
消费了一个数据food2
生产了一个数据food3
消费了一个数据food3
生产了一个数据food4
消费了一个数据food4
生产了一个数据food5
消费了一个数据food5
生产了一个数据food6
生产了一个数据food7
消费了一个数据food6
生产了一个数据food8
生产了一个数据food9
消费了一个数据food7
消费了一个数据food8
消费了一个数据food9
结果(阻塞)
 1 import time
 2 import random
 3 from multiprocessing import Process, Queue
 4 
 5 def consumer(name, q):
 6     while True:
 7         obj = q.get()
 8         print(f'{name}吃了一个{obj}')
 9         time.sleep(random.randint(1, 3))
10 
11 def producer(name, food, q):
12     for i in range(10):
13         time.sleep(random.randint(1, 5))
14         q.put(f'{name}生产的{food}{i}')
15         print(f'{name}生产了一个数据{food}{i}')
16 
17 if __name__ == '__main__':
18     q = Queue()
19     Process(target=consumer, args=('alex', q)).start()
20     Process(target=producer, args=('yuan', '泔水', q)).start()
21     Process(target=producer, args=('egon', '骨头', q)).start()
供大于求
D:\Python36\python.exe E:/Python/草稿纸.py
egon生产了一个数据骨头0
alex吃了一个egon生产的骨头0
yuan生产了一个数据泔水0
egon生产了一个数据骨头1
alex吃了一个yuan生产的泔水0
alex吃了一个egon生产的骨头1
yuan生产了一个数据泔水1
egon生产了一个数据骨头2
alex吃了一个yuan生产的泔水1
egon生产了一个数据骨头3
yuan生产了一个数据泔水2
alex吃了一个egon生产的骨头2
alex吃了一个egon生产的骨头3
egon生产了一个数据骨头4
alex吃了一个yuan生产的泔水2
yuan生产了一个数据泔水3
alex吃了一个egon生产的骨头4
alex吃了一个yuan生产的泔水3
yuan生产了一个数据泔水4
egon生产了一个数据骨头5
yuan生产了一个数据泔水5
alex吃了一个yuan生产的泔水4
yuan生产了一个数据泔水6
egon生产了一个数据骨头6
alex吃了一个egon生产的骨头5
yuan生产了一个数据泔水7
alex吃了一个yuan生产的泔水5
yuan生产了一个数据泔水8
alex吃了一个yuan生产的泔水6
egon生产了一个数据骨头7
alex吃了一个egon生产的骨头6
yuan生产了一个数据泔水9
alex吃了一个yuan生产的泔水7
egon生产了一个数据骨头8
alex吃了一个yuan生产的泔水8
egon生产了一个数据骨头9
alex吃了一个egon生产的骨头7
alex吃了一个yuan生产的泔水9
alex吃了一个egon生产的骨头8
alex吃了一个egon生产的骨头9
结果(consumer结束不了)
 1 import time
 2 import random
 3 from multiprocessing import Process, Queue
 4 
 5 
 6 def consumer(name, q):
 7     while True:
 8         obj = q.get()  # 阻塞
 9         if obj is None:
10             break
11         print(f'{name}吃了一个{obj}')
12         time.sleep(random.randint(1, 3))
13 
14 
15 def producer(name, food, q):
16     for i in range(10):
17         time.sleep(random.randint(1, 5))
18         q.put(f'{name}生产的{food}{i}')
19         print(f'{name}生产了一个{food}{i}')
20 
21 
22 if __name__ == '__main__':
23     q = Queue()
24     Process(target=consumer, args=('alex', q)).start()
25     Process(target=consumer, args=('wusir', q)).start()
26     p1 = Process(target=producer, args=('yuan', '泔水', q))
27     p1.start()
28     p2 = Process(target=producer, args=('egon', '骨头', q))
29     p2.start()
30     p1.join()
31     p2.join()
32     q.put(None)
33     q.put(None)
数据被消费完就结束进程
D:\Python36\python.exe E:/Python/草稿纸.py
egon生产了一个骨头0
alex吃了一个egon生产的骨头0
yuan生产了一个泔水0
wusir吃了一个yuan生产的泔水0
yuan生产了一个泔水1
alex吃了一个yuan生产的泔水1
egon生产了一个骨头1
yuan生产了一个泔水2
alex吃了一个egon生产的骨头1
wusir吃了一个yuan生产的泔水2
egon生产了一个骨头2
alex吃了一个egon生产的骨头2
yuan生产了一个泔水3
wusir吃了一个yuan生产的泔水3
egon生产了一个骨头3
wusir吃了一个egon生产的骨头3
yuan生产了一个泔水4
wusir吃了一个yuan生产的泔水4
egon生产了一个骨头4
alex吃了一个egon生产的骨头4
yuan生产了一个泔水5
wusir吃了一个yuan生产的泔水5
egon生产了一个骨头5
alex吃了一个egon生产的骨头5
egon生产了一个骨头6
wusir吃了一个egon生产的骨头6
yuan生产了一个泔水6
alex吃了一个yuan生产的泔水6
yuan生产了一个泔水7
alex吃了一个yuan生产的泔水7
egon生产了一个骨头7
wusir吃了一个egon生产的骨头7
yuan生产了一个泔水8
alex吃了一个yuan生产的泔水8
yuan生产了一个泔水9
wusir吃了一个yuan生产的泔水9
egon生产了一个骨头8
alex吃了一个egon生产的骨头8
egon生产了一个骨头9
wusir吃了一个egon生产的骨头9

Process finished with exit code 0
结果

  q.join()  对这个队列进行阻塞,这个队列中的所有值被取走,且执行了task_done.

 1 import time
 2 from multiprocessing import Process, JoinableQueue
 3 
 4 def consumer(q):
 5     while True:
 6         print(q.get())
 7         time.sleep(0.3)
 8         q.task_done()   # 通知队列一个数据已经被处理完了
 9 
10 if __name__ == "__main__":
11     q = JoinableQueue()
12     c = Process(target=consumer, args=(q,))
13     c.daemon = True
14     c.start()
15     for i in range(10):
16         q.put(i)    # 10个数据
17     q.join()    # join表示所有的数据都被取走且被处理完才结束阻塞
18     print('所有数据都被处理完了')
JoinableQueue
D:\Python36\python.exe E:/Python/草稿纸.py
0
1
2
3
4
5
6
7
8
9
所有数据都被处理完了

Process finished with exit code 0
结果
 1 import time
 2 import random
 3 from multiprocessing import Process, JoinableQueue
 4 
 5 def consumer(name, q):
 6     while True:
 7         obj = q.get()   # 阻塞
 8         print(f'{name}吃了一个{obj}')
 9         time.sleep(random.randint(1, 3))
10         q.task_done()
11 
12 def producer(name, food, q):
13     for i in range(10):
14         time.sleep(random.randint(1, 5))
15         q.put(f'{name}生产的{food}{i}')
16         print(f'{name}生产了一个{food}{i}')
17 
18 if __name__ == "__main__":
19     q = JoinableQueue()
20     c1 = Process(target=consumer, args=('alex', q))
21     c2 = Process(target=consumer, args=('wusir', q))
22     c1.daemon = True
23     c2.daemon = True
24     p1 = Process(target=producer, args=('yuan', '泔水', q))
25     p2 = Process(target=producer, args=('egon', '骨头', q))
26     c1.start()
27     c2.start()
28     p1.start()
29     p2.start()
30     p1.join()
31     p2.join()
32     q.join()
协调生产者与消费者之间的供给关系
D:\Python36\python.exe E:/Python/草稿纸.py
egon生产了一个骨头0
alex吃了一个egon生产的骨头0
yuan生产了一个泔水0
wusir吃了一个yuan生产的泔水0
egon生产了一个骨头1
wusir吃了一个egon生产的骨头1
egon生产了一个骨头2
alex吃了一个egon生产的骨头2
yuan生产了一个泔水1
wusir吃了一个yuan生产的泔水1
egon生产了一个骨头3
alex吃了一个egon生产的骨头3
yuan生产了一个泔水2
wusir吃了一个yuan生产的泔水2
egon生产了一个骨头4
alex吃了一个egon生产的骨头4
yuan生产了一个泔水3
wusir吃了一个yuan生产的泔水3
egon生产了一个骨头5
alex吃了一个egon生产的骨头5
yuan生产了一个泔水4
wusir吃了一个yuan生产的泔水4
yuan生产了一个泔水5
egon生产了一个骨头6
alex吃了一个yuan生产的泔水5
wusir吃了一个egon生产的骨头6
egon生产了一个骨头7
alex吃了一个egon生产的骨头7
yuan生产了一个泔水6
wusir吃了一个yuan生产的泔水6
yuan生产了一个泔水7
alex吃了一个yuan生产的泔水7
egon生产了一个骨头8
wusir吃了一个egon生产的骨头8
yuan生产了一个泔水8
alex吃了一个yuan生产的泔水8
egon生产了一个骨头9
wusir吃了一个egon生产的骨头9
yuan生产了一个泔水9
alex吃了一个yuan生产的泔水9

Process finished with exit code 0
结果

  队列:

    维护了一个先进先出的顺序.

    且保证了数据在进程之间的安全.

2、管道

3、数据共享

4、进程池

猜你喜欢

转载自www.cnblogs.com/ZN-225/p/9179112.html