multiprocessing 基於進程的“線程式”介面 python

來源:互聯網
上載者:User

標籤:python   多進程   

multiprocessing在python2.6+版本中得到應用。

multi意思為多個,processing意思為進程 也就是實現多進程。可以實現利用調用電腦的多個CPU實現多線程。

multiprocessing是一個包,支援使用類似threading模組的API產生進程。multiprocessing包提供本地和遠程兩種並發,通過使用子進程而非線程有效地迴避了全域解譯器鎖。 因此,multiprocessing模組允許程式員充分利用一個給定機器的多個處理器。它在Unix和Windows上都可允許。

下面主要介紹進程類

線程是通過建立Process對象,然後調用start()方法來產生的。Process繼承了threading.Thread的API。現在舉一個multiprocess 的例子:
使用Process建立進程:

from multiprocessing import Processdef f(name):    print ‘hello‘, nameif __name__ == ‘__main__‘:    p = Process(target=f, args=(‘bob‘,)) #建立一個線程    p.start() #調用start方法 啟動    p.join()  

下面是一個活的線程ID的例子:

from multiprocessing import Processimport osdef info(title):    print title    print ‘module name:‘, __name__    if hasattr(os, ‘getppid‘):  # 只在Unix中可使用        print ‘parent process:‘, os.getppid()    print ‘process id:‘, os.getpid()def f(name):    info(‘function f‘)    print ‘hello‘, nameif __name__ == ‘__main__‘:    info(‘main line‘)    p = Process(target=f, args=(‘bob‘,))    p.start()    p.join()

代碼中使用os的getpid()獲得父進程的ID 使用getip()獲得當前進程的ID,另外還可以使用getppid獲得父進程的父進程的ID。

IPC(Inter-Process Communication) 進程間的通訊

multiprocessing包中有Pipe類和Queue類來分別支援這兩種IPC機制。Pipe和Queue可以用來傳送常見的對象。
Pipe可以是單向(half-duplex),也可以是雙向(duplex)。我們通過mutiprocessing.Pipe(duplex=False)建立單向管道 (預設為雙向)。一個進程從PIPE一端輸入對象,然後被PIPE另一端的進程接收,單向管道只允許管道一端的進程輸入,而雙向管道則允許從兩端輸入。
舉例:(單向的)

from multiprocessing import Process, Pipedef f(conn): #conn為父線程傳遞過來的pipe對象    conn.send([42, None, ‘hello‘]) #在pipe對象的一端發送資料    conn.close() #關閉if __name__ == ‘__main__‘:    parent_conn, child_conn = Pipe() #定義兩個Pipe對象來建立     p = Process(target=f, args=(child_conn,))#建立一個進程 傳遞的參數為pipe對象    p.start()    print parent_conn.recv()   # prints "[42, None, ‘hello‘]" #在父進程中使用另一個pipe對象的recv()方法接受資料    p.join()

每個連線物件都有send和recv方法,需要注意的是,如果兩個進程或者線程同時讀取或寫入pipe對象的終端,則可能引起終端。如果同時使用pipe的不同終端則不會有風險。

下面舉例:(雙向)

import multiprocessing as muldef proc1(pipe):    pipe.send(‘hello‘)    print(‘proc1 rec:‘,pipe.recv())def proc2(pipe):    print(‘proc2 rec:‘,pipe.recv())    pipe.send(‘hello, too‘)if __name__ == ‘__main__‘:    mul.freeze_support()    pipe1,pipe2= mul.Pipe() #建立兩個pipe對象    # Pass an end of the pipe to process 1    p1 = mul.Process(target=proc1, args=(pipe1,)) #建立p1線程    # Pass the other end of the pipe to process 2    p2   = mul.Process(target=proc2, args=(pipe2,)) #建立p2線程    p1.start() #調用線程1    p2.start()  #調用線程2    p1.join()  #這裡等待線程1執行完成    p2.join()  #等待線程2執行完成#輸出:(‘proc2 rec:‘, ‘hello‘)(‘proc1 rec:‘, ‘hello, too‘)

這個例子實現了兩個線程之間的通訊,實現了雙向通訊。線程1: proc1中發送”hello”字串,線程proc2中接收線程1proc1中發送的”hello”字串並輸出,然後proc2發送”hello, too”字串,線程1 proc1接收到proc2發送的字串並輸出。

下面介紹另外一種實現IPC的方式:
Queue:
Queue與Pipe相類似,都是先進先出的結構。但Queue允許多個進程放入,多個進程從隊列取出對象。Queue使用mutiprocessing.Queue(maxsize)建立,maxsize表示隊列中可以存放對象的最大數量。
下面的程式展示了Queue的使用:

from multiprocessing import Process, Queuedef f(q):    q.put([42, None, ‘hello‘])  #調用主函數中p進程傳遞過來的進程參數 put函數為向隊列中添加一條資料。if __name__ == ‘__main__‘:    q = Queue() #建立一個Queue對象    p = Process(target=f, args=(q,)) #建立一個進程    p.start()    print q.get()    # prints "[42, None, ‘hello‘]"    p.join()

上面是一個queue的簡單應用,使用隊列q對象調用get函數來取得隊列中最先進入的資料。
舉一個複雜些的例子:

import multiprocessingimport time# 向queue中輸入資料的函數def inputQ(queue):    info = str(os.getpid()) + ‘(put):‘ + str(time.time())    queue.put(info)# 向queue中輸出資料的函數def outputQ(queue,lock):    info = queue.get()    lock.acquire()    print (str(os.getpid()) + ‘(get):‘ + info)    lock.release()# Mainif __name__ == ‘__main__‘:    multiprocessing.freeze_support()    record1 = []   # store input processes    record2 = []   # store output processes    lock  = multiprocessing.Lock()    #使用鎖方法輸出錯亂    queue = multiprocessing.Queue(3)    # 輸入進程    for i in range(10):        process = multiprocessing.Process(target=inputQ,args=(queue,))        process.start()        record1.append(process)    # 輸出進程    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()  # 如果沒有資料進入隊列中則關閉隊列    for p in record2:        p.join()#輸出結果為:15212(get):7180(put):1440649672.228820(get):7020(put):1440649672.856164(get):7872(put):1440649673.3910904(get):9436(put):1440649673.685016(get):16840(put):1440649674.0712004(get):12848(put):1440649674.3814456(get):11608(put):1440649674.662468(get):16884(put):1440649674.856464(get):8944(put):1440649674.897576(get):15476(put):1440649674.92

這個例子中,建立了二十個進程,十個是用來寫入隊列資料的,另外十個是用來輸出隊列中的資料的。

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

multiprocessing 基於進程的“線程式”介面 python

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.