1. 程式人生 > >Python多程序(multiprocessing)一

Python多程序(multiprocessing)一

目錄

簡介

多程序相對於多執行緒可以更好的使用多核,避開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