进程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

 

posted @ 2019-05-07 19:17  zhoyong  阅读(183)  评论(0编辑  收藏  举报