python中的multiprocessing模块支持两种方式在进程间通信,都是基于消息传递机制。之前我们介绍过,由于缺乏同步机制因此不得不采取消息传递机制,在进程间传递复制的数据。
##使用multiprocessing.Pipe模块
pipe管道在两个端点间搭建一种通信机制,通过在进程间建立通道使得进程间可以相互通信。
为了更好的说明multiprocessing.Pipe对象的使用方法,我们将介绍一个python程序,包含A,B两个进程。进程A发送1到10之间的一个数给进程B,进程B将打印该数,接下来让我们一步步介绍这个程序。
我们首先导入一些我们程序中需要的包,如下:
import os, random
from multiprocessing import Process, Pipe
通过os模块的os.getpid()方法使得我们获得进程的PID。os.getpid()将以一种透明的方式返回程序的PID,在我们的程序中,它分别返回producer_task进程和consumer_task进程的PID。
下面我们将定义producer_task方法,该方法返回1到10之间的一个随机数。producer_task方法的关键是调用conn.send方法,conn以参数的形式在主函数中被传給producer_task方法。producer_task方法如下:
def producer_task(conn):
value = random.randint(1, 10)
conn.send(value)
print('Value [%d] send by PID [%d]' % (value, os.getpid()))
conn.close()
consumer进程将要执行的任务也很简单,它唯一的任务就是接收A进程传递过来的参数,接收本进程的PID,最终打印出来。consumer进程的中传入的consumer_task方法如下:
def consumer_task(conn)
print('Value [%d] received by PID [%d]' % (conn.recv(), os.getpid()))
最后一块将介绍如何调用Pipe()方法创建两个连接对象分别用于producer进程和consumer进程,然后通过参数形式各自传递到consumer_task方法和producer_task方法中去,主函数具体如下所是:
if __name__ == '__main__':
producer_conn, consumer_conn = Pipe()
consumer = Process(target=consumer_task,args=(consumer_conn,))
producer = Process(target=producer_task,args=(producer_conn,))
consumer.start()
producer.start()
consumer.join()
producer.join()
定义好进程之后,我们便可以调用进程对象的start方法开始执行进程,join方法用于分别等待producer进程和consumer进程执行完毕。下面的截图中我们将看到程序的输出:
##理解multiprocessing.Queue模块 之前小节中我们分析了如何在进程间创建通信通道来传递消息,现在我们将分析如何更有效的传递消息,这里我们使用mutilprocessing模块下的Queue对象。multoprocessing.Queue对象方法和queue.Queue对象方法类似。然后内在实现却不尽相同,比如multiprocess模块使用了内部线程feeder,把缓冲区中的数据传入目标进程相关连接的管道中。管道和队列机制均使用了消息传递机制,节省了使用同步机制带来的开销。