Python多程序(multiprocessing)一
阿新 • • 發佈:2019-02-16
目錄
簡介
多程序相對於多執行緒可以更好的使用多核,避開GIL(Global Interpreter Lock)的影響。而且多程序引入了程序池的概念,可以更好的並行處理不同輸入的資料。
Process 類
在多程序中,通過建立Process物件和呼叫start()函式來生成一個新的程序。Process類似於threading.Thread。
from multiprocessing import Process
import os
def info(title):
print title
print 'module name:', __name__
if hasattr(os, 'getppid'):
print 'parent process:', os.getppid()
print 'process id:', os.getpid()
def f(name):
info('function f')
print 'hello', name
if __name__ == '__main__':
info('main line')
p = Process(target=f, args=('bob',))
p.start()
p.join()
輸出結果為:
main line
module name: __main__
parent process: 9335
process id: 128831
function f
module name: __main__
parent process: 128831
process id: 129413
hello bob
即建立了一個程序,來執行函式。
程序間通訊
在python的多程序中,主要有兩種通訊方式:Queues和Pipes
Queues
from multiprocessing import Process, Queue
def f(q):
q.put([42, None, 'hello'])
if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print q.get()
p.join()
輸出結果:
[42, None, 'hello']
一個簡單的程序間通訊的列子,writer從已有的queue中讀取資料,並將資料加一寫入out_queue當中,reader從out_queue當中讀取writer寫入的資料並將其輸出。比較需要注意的是,在multiprocessing中的Queue,包含Queue類的所有功能除了join()和task_done(),所以當需要用到這兩個函式的時候,需要使用JoinableQueue()。
import multiprocessing
queue = multiprocessing.JoinableQueue()
out_queue = multiprocessing.JoinableQueue()
class WriterProcess(multiprocessing.Process):
def __init__(self, queue, out_queue):
multiprocessing.Process.__init__(self)
self.queue = queue
self.out_queue = out_queue
def run(self):
while True:
tmp = self.queue.get()
tmp += 1
self.out_queue.put(tmp)
self.queue.task_done()
class ReaderProcess(multiprocessing.Process):
def __init__(self, queue):
multiprocessing.Process.__init__(self)
self.queue = queue
def run(self):
while True:
tmp = self.queue.get()
print tmp
self.queue.task_done()
def main():
for i in range(5):
queue.put(i)
for i in range(3):
pw = WriterProcess(queue, out_queue)
pw.daemon = True
pw.start()
for i in range(2):
pr = ReaderProcess(out_queue)
pr.daemon = True
pr.start()
queue.join()
out_queue.join()
main()
程序間同步
from multiprocessing import Process, Lock
import time
def f(l, i):
l.acquire()
print 'Hello World', i
time.sleep(1)
print i, "end"
l.release()
if __name__ == '__main__':
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()
輸出結果為:
Hello World 0
0 end
Hello World 1
1 end
Hello World 2
2 end
Hello World 3
3 end
Hello World 4
4 end
Hello World 5
5 end
Hello World 6
6 end
Hello World 7
7 end
Hello World 8
8 end
Hello World 9
9 end
如果不用鎖的話,輸出結果如下:
Hello World 0
Hello World 1
Hello World 2
Hello World 3
Hello World 4
Hello World 5
Hello World 6
Hello World 7
Hello World 8
Hello World 9
0 end
1 end
3 2end
end
45 end
end
76 endend
89 endend