点击上方蓝字,关注我们
在Python中,进程之间互相隔离,但是进程之间是需要互相通信的,在进程中可以通过两种方式实现进程之间的数据通信(传输):队列和管道。这两种方式都可以实现消息的传递。队列使用到的关键字是Queue。下面具体演示队列方法的基本使用,具体案例代码如下:
#!/usr/bin/env python
#!coding:utf-8
from multiprocessing import Process,Queue
import os
import time as t
def queueTest():
'''队列的基本使用'''
q=Queue(3)
for item in range(3):
q.put(item)
print('判断队列是否已满:',q.full())
#队列已满的情况下,如果再放,就会出现堵塞。
for item in range(3):
print(q.get(item))
print('判断队列是否已空:',q.empty())
if __name__ == '__main__':
queueTest()
在队列里面,特别需要注意的是在队列已满以及队列已空的情况下,如果再加入新的对象以及队列为空的情况下获取新的对象,都会导致阻塞的。这个也是在服务端的测试中特别需要注意的点,也是在测试中针对队列特别需要考虑的测试测试点。下面基于队列的机制,来实现一个生产者消费者的模式,涉及到的代码如下:
#!/usr/bin/env python
#!coding:utf-8
from multiprocessing import Process,Queue
import time as t
import random
import os
def producer(q,name,food):
for item in range(3):
t.sleep(random.randrange(1,3))
res='{0} is {1}'.format(food,item)
q.put(res)
print('\033[32m{0}生产了{1}的数据\033[0m'.format(name,res))
def consumer(q,name):
while True:
res=q.get()
#判断如果是为空的队列,立刻跳出,不会堵塞
if res is None:break
t.sleep(random.randrange(1,3))
print('\033[34m{0} 消费了 {1}\033[0m'.format(name,res))
if __name__ == '__main__':
q=Queue()
p=Process(target=producer,args=(q,'lisi','包子'))
c=Process(target=consumer,args=(q,'lisi'))
p.start()
p.join()
#发送None,防止队列堵塞
q.put(None)
c.start()
生产者消费者的模式其实很好理解的,生产者往队列里面新增数据,而消费者通过队列里面获取数据,但是前提是同一个队列的,如下显示的是执行后的信息,具体如下所示:
下面再来看进程间通信的另外一种机制是管道,多进程编程的方式,和实际生活中的管(管道)是非常类似的。通常情况下,管道有 2 个口,而 Pipe 也常用来实现 2 个进程之间的通信,这 2 个进程分别位于管道的两端,一端用来发送数据,另一端用来接收数据。使用 Pipe 实现进程通信,首先需要调用 multiprocessing.Pipe() 函数来创建一个管道。该函数的语法格式如下:
conn1, conn2 = multiprocessing.Pipe( [duplex=True] )
其中,conn1 和 conn2 分别用来接收 Pipe 函数返回的 2 个端口;duplex 参数默认为 True,表示该管道是双向的。下面具体通过代码来说明这部分的应用,涉及代码如下:
#!/usr/bin/env python
#!coding:utf-8
from multiprocessing import Process,Pipe
import multiprocessing
def pipeFunc(conn,name):
print('进程{0}发送数据'.format(multiprocessing.current_process().pid))
conn.send(name)
if __name__ == '__main__':
#创建管道
conn1,conn2=Pipe()
obj=Process(target=pipeFunc,args=(conn1,'无涯课堂为您服务!'))
obj.start()
obj.join()
print('进程{0}接收数据'.format(multiprocessing.current_process().pid))
print(conn2.recv())
在如上代码中,可以看到,在同一个管道中,一个负责发,另外一个接收数据,实现进程之间的数据通信。