上面写了Python如何建立多个进程,可是前面文章中建立的进程都是哑吧和聋子,本身顾本身执行,不会相互交流。
那么如何让进程间相互说说话呢?
Python为咱们提供了一个函数multiprocessing.Pipe
和一个类:multiprocessing.Queue。python
multiprocessing.Pipe()
multiprocessing.Pipe()即管道模式,调用Pipe()返回管道的两端的Connection。dom
Python官方文档的描述:
Returns a pair (conn1, conn2) of Connection objects representing the ends of a pipe.
所以, Pipe仅仅适用于只有两个进程一读一写的单双工状况,也就是说信息是只向一个方向流动。例如电视、广播,看电视的人只能看,电视台是能播送电视节目。函数
Pipe的读写效率要高于Queue。
进程间的Pipe基于fork机制创建。
当主进程建立Pipe的时候,Pipe的两个Connections链接的的都是主进程。
当主进程建立子进程后,Connections也被拷贝了一份。此时有了4个Connections。
此后,关闭主进程的一个Out Connection,关闭一个子进程的一个In Connection。那么就创建好了一个输入在主进程,输出在子进程的管道。
原理示意图以下:
code
# 示例代码 # coding=utf-8 from multiprocessing import Pipe, Process def son_process(x, pipe): _out_pipe, _in_pipe = pipe # 关闭fork过来的输入端 _in_pipe.close() while True: try: msg = _out_pipe.recv() print msg except EOFError: # 当out_pipe接受不到输出的时候且输入被关闭的时候,会抛出EORFError,能够捕获而且退出子进程 break
if __name__ == '__main__': out_pipe, in_pipe = Pipe(True) son_p = Process(target=son_process, args=(100, (out_pipe, in_pipe))) son_p.start() # 等pipe被fork 后,关闭主进程的输出端 # 这样,建立的Pipe一端链接着主进程的输入,一端链接着子进程的输出口 out_pipe.close() for x in range(1000): in_pipe.send(x) in_pipe.close() son_p.join() print "主进程也结束了"
总结一下:队列
上面的代码中主要用到了pipe的send()、recv()、close()方法。当pipe的输入端被关闭,且没法接收到输入的值,那么就会抛出EOFError。
新建一个Pipe(duplex)的时候,若是duplex为True,那么建立的管道是双向的;若是duplex为False,那么建立的管道是单向的。
multiprocessing.Queue
Queue据官方文档也是基于pipe的实现。
Queue的使用主要是一边put(),一边get().可是Queue能够是多个Process 进行put操做,也能够是多个Process进行get()操做。
Demo:进程
# coding=utf-8 from multiprocessing import Queue, Process from Queue import Empty as QueueEmpty import random def getter(name, queue): print 'Son process %s' % name while True: try: value = queue.get(True, 10) # block为True,就是若是队列中无数据了。 # |—————— 若timeout默认是None,那么会一直等待下去。 # |—————— 若timeout设置了时间,那么会等待timeout秒后才会抛出Queue.Empty异常 # block 为False,若是队列中无数据,就抛出Queue.Empty异常 print "Process getter get: %f" % value except QueueEmpty: break def putter(name, queue): print "Son process %s" % name for i in range(0, 1000): value = random.random() queue.put(value) # 放入数据 put(obj[, block[, timeout]]) # 若block为True,如队列是满的: # |—————— 若timeout是默认None,那么就会一直等下去 # |—————— 若timeout设置了等待时间,那么会等待timeout秒后,若是仍是满的,那么就抛出Queue.Full. # 若block是False,若是队列满了,直接抛出Queue.Full print "Process putter put: %f" % value if __name__ == '__main__': queue = Queue() getter_process = Process(target=getter, args=("Getter", queue)) putter_process = Process(target=putter, args=("Putter", queue)) getter_process.start() putter_process.start()
Queue的一些说明已经写在代码中了。ip