1.簡介:
multiprocessing 是一個和threading模塊相似的包,支持生成多進程。multiprocessing 包提供包括本地和遠端的并發(fā)性,通過使用多進程有效避免了因GIL的限制。由此, multiprocessing包允許程序員充分利用多進程。該包可運行在Unix和Windows上。舉例:
def f(x):
return x*x
def create_pro_pool():
# 對Pool對象調(diào)用join()方法會等待所有子進程執(zhí)行完畢,調(diào)用join()之前必須先調(diào)用close(),調(diào)用close()之后就不能繼續(xù)添加新的Process了。
# 由于Pool的默認大小是CPU的核數(shù),如果你不幸擁有8核CPU,你要提交至少9個子進程才能看到上面的等待效果。
p = Pool()
for i in range(5):
print(p.map(f, [1, 2, 3]))
p.close()
p.join()
if __name__ == '__main__':
# create_child_pro()
# create_child_pro_pool()
# pros_communication()
create_pro_pool()
結(jié)果輸出:
[1, 4, 9]
[1, 4, 9]
[1, 4, 9]
[1, 4, 9]
[1, 4, 9]
在multiprocessing中, 進程的產(chǎn)生是通過創(chuàng)建一個Process類并調(diào)用他的start()方法。舉個例子:
import os
import time
import random
from multiprocessing import Process, Pool, Queue
def run_proc(name):
print 'Run child process %s (%s)...' % (name, os.getpid())
def create_child_pro():
# 創(chuàng)建子進程時,只需要傳入一個執(zhí)行函數(shù)和函數(shù)的參數(shù),創(chuàng)建一個Process實例,用start()方法啟動
# join()方法可以等待子進程結(jié)束后再繼續(xù)往下運行,通常用于進程間的同步。
print 'Parent process %s.' % os.getpid()
p = Process(target=run_proc, args=('test',))
print 'Process will start.'
p.start()
p.join()
print 'Process end.'
if __name__ == '__main__':
create_child_pro()
# create_child_pro_pool()
# pros_communication()
# create_pro_pool()
運行結(jié)果:
Parent process 13032.
Process will start.
Run child process test (11900)...
Process end.
進程間通信方式(Queue, Pipe):
import os
import time
import random
from multiprocessing import Process, Pool, Queue
# 寫數(shù)據(jù)進程執(zhí)行的代碼:
def write(q):
for value in ['A', 'B', 'C']:
print 'Put %s to queue...' % value
q.put(value)
time.sleep(random.random())
# 讀數(shù)據(jù)進程執(zhí)行的代碼:
def read(q):
while True:
value = q.get(True)
print 'Get %s from queue.' % value
def pros_communication():
# 父進程創(chuàng)建Queue,并傳給各個子進程:
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
# 啟動子進程pw,寫入:
pw.start()
# 啟動子進程pr,讀取:
pr.start()
# 等待pw結(jié)束:
pw.join()
# pr進程里是死循環(huán),無法等待其結(jié)束,只能強行終止:
pr.terminate()
if __name__ == '__main__':
# create_child_pro()
# create_child_pro_pool()
pros_communication()
# create_pro_pool()
# pros_communication_pipe()
運行結(jié)果:
Put A to queue...
Get A from queue.
Put B to queue...
Get B from queue.
Put C to queue...
Get C from queue.
Pipe
import os
import time
import random
from multiprocessing import Process, Pool, Queue, Pipe
def f_pipe(conn):
conn.send([42, None, 'hello'])
conn.close()
def pros_communication_pipe():
# The Pipe() function returns a pair of connection objects connected by a pipe which
# by default is duplex (two-way).
# The two connection objects returned by Pipe() represent the two ends of the pipe.
# Each connection object has send() and recv() methods (among others).
parent_conn, child_conn = Pipe()
print parent_conn, child_conn
p = Process(target=f_pipe, args=(child_conn,))
p.start()
print(parent_conn.recv()) # prints "[42, None, 'hello']"
p.join()
if __name__ == '__main__':
# create_child_pro()
# create_child_pro_pool()
# pros_communication()
# create_pro_pool()
pros_communication_pipe()
運行結(jié)果:
[42, None, 'hello']
進程間鎖機制:
import os
import time
import random
from multiprocessing import Process, Pool, Queue, Pipe, Lock
def f_lock(l, i):
l.acquire()
try:
print('hello world', i)
finally:
l.release()
def pros_communication_lock():
lock = Lock()
for num in range(10):
Process(target=f_lock, args=(lock, num)).start()
if __name__ == '__main__':
# create_child_pro()
# create_child_pro_pool()
# pros_communication()
# create_pro_pool()
# pros_communication_pipe()
pros_communication_lock()
運行結(jié)果:
('hello world', 3)
('hello world', 2)
('hello world', 1)
('hello world', 0)
('hello world', 4)
('hello world', 6)
('hello world', 5)
('hello world', 7)
('hello world', 8)
('hello world', 9)