multiprocessing 提供了 threading 包中没有的 IPC,效率上更高。应优先考虑 Pipe 和 Queue,避免
使用 Lock/Event/Semaphore/Condition 等同步方式 (因为它们占据的不是用户进程的资源)。
multiprocessing 包中有 Pipe 类和 Queue 类来分别支持这两种 IPC 机制。Pipe 和 Queue 可以用来传
送常见的对象。
(1) Pipe 可 以 是 单 向 (half-duplex) , 也 可 以 是 双 向 (duplex) 。 我 们 通 过
mutiprocessing.Pipe(duplex=False)创建单向管道 (默认为双向)。一个进程从 PIPE 一端输入对象,然
后被 PIPE 另一端的进程接收,单向管道只允许管道一端的进程输入,而双向管道则允许从两端输入。
pipe.py
#coding=utf-8
import multiprocessing
def proc1(pipe):
pipe.send('hello')
print('proc1 rec:',pipe.recv())
def proc2(pipe):
print('proc2 rec:',pipe.recv())
pipe.send('hello, too')
pipe = multiprocessing.Pipe()
p1 = multiprocessing.Process(target=proc1, args=(pipe[0],))
p2 = multiprocessing.Process(target=proc2, args=(pipe[1],))
p1.start()
p2.start()
p1.join()
p2.join()
注:本程序只能在 linux/Unix 上运行,运行结果:
Ubuntu
'proc2 rec:','hello'
'proc2 rec:','hello,too'
这里的 Pipe 是双向的。Pipe 对象建立的时候,返回一个含有两个元素的表,每个元素代表 Pipe 的一
端(Connection 对象)。我们对 Pipe 的某一端调用 send()方法来传送对象,在另一端使用 recv()来接收。
(2) Queue 与 Pipe 相类似,都是先进先出的结构。但 Queue 允许多个进程放入,多个进程从队列取
出对象。Queue 使用 mutiprocessing.Queue( maxsize )创建,maxsize 表示队列中可以存放对象的最大数量。
queue.py
#coding=utf-8
import multiprocessing
import time,os
#input worker
def inputQ(queue):
info = str(os.getpid()) + '(put):' + str(time.time())
queue.put(info)
#output worker
def outputQ(queue,lock):
info = queue.get()
lock.acquire()
print (str(os.getpid()) + '(get):' + info)
lock.release()
#Main
record1 = [] # store input processes
record2 = [] # store output processes
lock = multiprocessing.Lock() # 加锁,为防止散乱的打印
queue = multiprocessing.Queue(3)
#input processes
for i in range(10):
process = multiprocessing.Process(target=inputQ,args=(queue,))
process.start()
record1.append(process)
#output processes
for i in range(10):
process = multiprocessing.Process(target=outputQ,args=(queue,lock))
process.start()
record2.append(process)
for p in record1:
p.join()
queue.close() # 没有更多的对象进来,关闭 queue
for p in record2:
p.join()
注:本程序只能在 linux/Unix 上运行,运行结果
Ubuntu
2702(get):2689(put):1387947815.56
2704(get):2691(put):1387947815.58
2706(get):2690(put):1387947815.56
2707(get):2694(put):1387947815.59
2708(get):2692(put):1387947815.61
2709(get):2697(put):1387947815.6
2703(get):2698(put):1387947815.61
2713(get):2701(put):1387947815.65
2716(get):2699(put):1387947815.63
2717(get):2700(put):1387947815.62应用于自动化测试
因为多进程/多线程特性在 Python 中属于比较高级的应用,对于初学者来说理解起来有一定的难度,
所以我们通过相当的篇幅和实例来进行讲解,目的是为了让读者深入的理解Python 的多进程/多线程技术。