进程2
9.进程间通信
IPC机制(InterProcess Communication),指两个进程之间进行数据交换的过程
进程与进程间的数据是隔离的,通信需要介质:管道 / 队列(管道+锁)
队列:先进先出
堆栈:先进后出
队列的特点:
设置一个队列q:在存放值和取值的时候都会出现阻塞的情况(队列满了,队列空了)
1、q.put():放入值
2、q.get():获取队列里面的值(同一时刻只能有一个任务来队列中获取数据)
3、q.get_nowait():数据时,跟get取值一样,没有数据时,直接报错
4、q.empty():判断队列是否为空,需要注意的是,在并发的情况下,这个方法判断不准确!
5、q.full():判断是否达到队列的最大存储个数
关于队列
from multiprocessing import Queue q = Queue(9) # 产生一个最多能够存放9个数据的队列 q.put(1) q.put(3) q.put(4) print(q.full()) q.put(2) q.put(5) for i in range(4): q.put(i) print(q.get()) # 取数据,get一次就取一个;有取无等 print(q.get()) print(q.get()) print(q.get_nowait()) # 有数据,取,无则报错 a = q.get_nowait() print(a, q.qsize) print(q.empty()) # 判断队列是否为空,但在并发的情况下,判断不准确 >>>: False 1 3 4 2 5 <bound method Queue.qsize of <multiprocessing.queues.Queue object at 0x000002C2F7348320>> False
利用队列 Queue 实现进程间通信
from multiprocessing import Queue, Process def producer(q): q.put('hello baby!') def consumer(q): print(q.get()) if __name__ == '__main__': q = Queue() # 生成一个队列对象 p1 = Process(target=producer, args=(q,)) c1 = Process(target=consumer, args=(q,)) p1.start() c1.start() >>>: hello baby!
10.生产者消费者模型(***)
例如:
生产者: 生产数据的 如做包子的
消费者: 处理数据的 如买包子的
两者之间的通信介质:队列/管道
供需不平衡:
队列: 生产者生产的数据放到队列里面
消费者去队列里面获取数据
解决供需不平衡的问题:
定义一个队列,用来存放固定数量的数据
生产者和消费者不需直接打交道,两者都通过队列实现数据传输
Queue:管道+锁
from multiprocessing import Process, Queue import time import random def producer(name, food, q): for i in range(2): data = "%s produce %s No.%s" % (name, food, i) time.sleep(random.randint(1,2)) print(data) q.put(data) def consumer(name, q): while True: data = q.get() if data is None: break time.sleep(random.random()) print('%s ate %s' % (name, data)) if __name__ == '__main__': q = Queue() p2 = Process(target=producer, args=('大厨tank', '包子', q)) c2 = Process(target=consumer, args=('Zero', q)) p2.start() c2.start() p2.join() # 在生产者生产完数据之后,往队列里面放一个提示性的消息,告诉消费者已经没有数据,你走吧,不要等了 q.put(None) c2.join() print('主') >>>: 大厨tank produce 包子 No.0 Zero ate 大厨tank produce 包子 No.0 大厨tank produce 包子 No.1 Zero ate 大厨tank produce 包子 No.1 主
JoinableQueue:
from multiprocessing import Process, JoinableQueue import time import random def producer(name, food, q): for i in range(3): data = '%s生产的%s %s' % (name, food, i) time.sleep(random.random()) print(data) q.put(data) # 将生产的数据放入队列中 def consumer(name, q): while True: data = q.get() if data is None: break time.sleep(random.random()) print('%s吃了%s' % (name, data)) q.task_done() # 告诉你的队列,你已经将数据取出并且处理完毕 if __name__ == '__main__': q = JoinableQueue() # 生成一个队列对象 p1 = Process(target=producer, args=('大厨a', 'noodle', q)) c1 = Process(target=consumer, args=('tom', q)) p1.start() c1.daemon = True c1.start() # 等待生产者生产完所有的数据 p1.join() q.join() # 等待队列中数据全部取出 print('主') >>>: 大厨a生产的noodle 0 大厨a生产的noodle 1 tom吃了大厨a生产的noodle 0 大厨a生产的noodle 2 tom吃了大厨a生产的noodle 1 tom吃了大厨a生产的noodle 2 主