进程之间的通信——队列

进程之间的通信叫做IPC

IPC(Inter-Process Communication)

 

from multiprocessing import Queue
import time
q=Queue(5)#生成5个队列
q.put(0)#往队列里面放内容
q.put(1)
q.put(2)
q.put(3)
q.put(4)
print(q.full())
q.get()#从队列里面取出来
q.get()
q.get()
q.get()
q.get()
print(q.empty())
while 1:
    try:
        q.get_nowait()
    except:
        print('队列已空')
        time.sleep(1)

延申

from multiprocessing import Queue,Process

def produce():
    print('hello')

if __name__=='__main__':
    q=Queue()
    p=Process(target=produce)
    p.start()
    print(q.get())

通过上面的代码,实现了主进程和子进程之间的互动。数据传输

再延申

from multiprocessing import Queue,Process

def produce(q):
    q.put('hello')
def consumer(q):
    print(q.get())

if __name__=='__main__':
    q=Queue()
    p=Process(target=produce,args=(q,))
    p.start()
    c = Process(target=consumer,args=(q,))
    c.start()

通过上面的代码实现了两个子进程之间的数据传输。

生产者和消费者模型;

from multiprocessing import Queue,Process
import time
import random

def producer(name,food,q):
    for i in range(10):
        time.sleep(random.randint(1,2))#加上这句话,能够延迟生产包子的时间更贴近于实际生活
        f= '%s生产了%s%s'%(name,food,i)
        print(f)
        q.put(f)

def consumer(q,name):
    while 1:
        food=q.get()
        print('\033[31m%s消费了%s\033[0m'%(name,food))
        time.sleep(random.randint(1, 2))  # 加上这句话,能够延迟吃包子的时间更贴近于实际生活,此外可以在这里调整时间来使得生产者和消费者之间的生产速度和消费速度相互匹配


if __name__=='__main__':
    q=Queue(20)
    p1=Process(target=producer,args=('tom','包子',q))
    p1.start()
    p2 = Process(target=producer, args=('Tim', '馒头', q))
    p2.start()
    c = Process(target=consumer,args=(q,'jack'))
    c.start()

上面两个生产者,一个消费者,构成了生产者和消费者模型。

但是上面的代码有一个问题就是:消费者里面有一个while循环,当消费者消费完所有生产者生产的食物后,代码并没有立即关闭,而是由于while循环的存在而阻塞。

from multiprocessing import Queue,Process
import time
import random

def producer(name,food,q):
    for i in range(10):
        time.sleep(random.randint(1,2))#加上这句话,能够延迟生产包子的时间更贴近于实际生活
        f= '%s生产了%s%s'%(name,food,i)
        print(f)
        q.put(f)

def consumer(q,name):
    while 1:
        food=q.get()
        if food is None:#这里加上这行代码后,当整个代码执行结束之后,就不会发生阻塞了
            break
        print('\033[31m%s消费了%s\033[0m'%(name,food))
        time.sleep(random.randint(1, 2))  # 加上这句话,能够延迟吃包子的时间更贴近于实际生活,此外可以在这里调整时间来使得生产者和消费者之间的生产速度和消费速度相互匹配

if __name__=='__main__':
    q=Queue(20)
    p1=Process(target=producer,args=('tom','包子',q))
    p1.start()
    p2 = Process(target=producer, args=('Tim', '馒头', q))
    p2.start()
    c = Process(target=consumer,args=(q,'jack'))
    c.start()
    p1.join()
    p2.join()
    q.put(None)#注意队列和锁是一个道理,总共有多少个消费者这里就需要重复几次这里的代码

上面的代码中如果有多个consumer,那么就需要写多个q.put(None),这里有更为简便的方法

from multiprocessing import JoinableQueue,Process
import time
import random

def producer(name,food,q):
    for i in range(10):
        time.sleep(random.randint(1,2))#加上这句话,能够延迟生产包子的时间更贴近于实际生活
        f= '%s生产了%s%s'%(name,food,i)
        print(f)
        q.put(f)
    # q.join()#这里需要注意:当从队列中的数据开始被放入且未取出之前这里都是处于阻塞状态,这段代码再老师课堂上有,自己感觉去掉这行代码以后也没什么影响,再学习

def consumer(q,name):
    while 1:
        food=q.get()
        print('\033[31m%s消费了%s\033[0m'%(name,food))
        time.sleep(random.randint(1, 2))  # 加上这句话,能够延迟吃包子的时间更贴近于实际生活,此外可以在这里调整时间来使得生产者和消费者之间的生产速度和消费速度相互匹配
        q.task_done()#表明队列中的数据被完全取出

if __name__=='__main__':
    q=JoinableQueue(20)
    p1=Process(target=producer,args=('tom','包子',q))
    p1.start()
    p2 = Process(target=producer, args=('Tim', '馒头', q))
    p2.start()
    c = Process(target=consumer,args=(q,'jack'))
    c.daemon=True#表示主进程中的代码执行结束之后,cosumer进程中的代码自动结束,也就是说当p1.join()和p2.join()结束之后这里才会自动结束
    c.start()
    p1.join()
    p2.join()

 

posted @ 2019-04-10 23:32  舒畅123  阅读(101)  评论(0编辑  收藏  举报