1. 程式人生 > >day-4 python多進程編程知識點匯總

day-4 python多進程編程知識點匯總

join() style 提高 href AI 隊列 線程 共享資源 man

1、 python多進程簡介

  由於Python設計的限制(我說的是咱們常用的CPython)。最多只能用滿1個CPU核心。Python提供了非常好用的多進程包multiprocessing,他提供了一套和多線程類似的接口,有start、run等方法,我們只需要定義一個函數,Python會替我們完成其他所有事情。借助這個包,可以輕松完成從單進程到並發執行的轉換。

2、 註意事項

  a)在UNIX平臺上,當某個進程終結之後,該進程需要被其父進程調用wait,否則進程成為僵屍進程(Zombie)。所以,有必要對每個Process對象調用join()方法 (實際上等同於wait)。對於多線程來說,由於只有一個進程,所以不存在此必要性。

  b)multiprocessing提供了threading包中沒有的IPC(比如Pipe和Queue),效率上更高。應優先考慮Pipe和Queue,避免使用Lock/Event/Semaphore/Condition等同步方式 (因為它們占據的不是用戶進程的資源)。

  c)多進程應該避免共享資源。在多線程中,我們可以比較容易地共享資源,比如使用全局變量或者傳遞參數。在多進程情況下,由於每個進程有自己獨立的內存空間,以上方法並不合適。此時我們可以通過共享內存和Manager的方法來共享資源。但這樣做提高了程序的復雜度,並因為同步的需要而降低了程序的效率。

3、 常用接口

  Event():進程的事件用於主線程控制其他進程的執行,事件主要提供了三個方法wait、clear、set

  Queue():進程的隊列,提供get和put方法

  Process():創建一個新的進程

  Lock():進程鎖

  Semaphore:一種帶計數的進程同步機制,當調用release時,增加計算,當acquire時,減少計數,當計數為0時,自動阻塞,等待release被調用

  Pipe():創建進程雙向管道

  Manager():一種較為高級的多進程通信方式,它能支持Python支持的的任何數據結構,不限制多進程是否源於同一個父進程

  Lock():進程鎖

  Pool():可以提供指定數量的進程供用戶調用,當有新的請求提交到pool中時,如果池還沒有滿,那麽就會創建一個新的進程用來執行該請求;但如果池中的進程數已經達到規定最大值,那麽該請求就會等待,直到池中有進程結束,才會創建新的進程來它。

  Condition():Condition被稱為條件變量,除了提供與Lock類似的acquire和release方法外,還提供了wait和notify方法。

  技術分享圖片

4、 代碼實例

技術分享圖片
‘‘‘
學習多線程通信:Queue,Pipe,Manage,Event
‘‘‘

import multiprocessing
import time

#循環從進程隊列中取數據
def Proceedataget(q,p,parent_event,child_event,manage_d,manage_l):
    for i in range(10):
        print(q.get())

    for i in range(20,30):
        p.send(i)
    parent_event.set()
    child_event.wait()

    for i in range(20,30):
        print("B process:" + str(p.recv()))

    manage_d["1"] = 1
    manage_l.append("2")

#循環從進程隊列中寫數據
def Proceedataput(q,p,parent_event,child_event,manage_d,manage_l):
    for i in range(10):
        q.put(i)

    for i in range(40,50):
        p.send(i)

    child_event.set()
    parent_event.wait()
    for i in range(20,30):
        print("A process:" + str(p.recv()))

    manage_d["2"] = 2
    manage_l.append("2")

if __name__ == "__main__":

    start_time = time.time()

    #定義一個進程隊列
    q = multiprocessing.Queue()
    #定義一個進程雙向管道
    parent_conn,child_conn = multiprocessing.Pipe()
    #定義兩個進程事件
    parent_event = multiprocessing.Event()
    child_event = multiprocessing.Event()
    multiprocessing.
    #定義連個Manager對象
    manage = multiprocessing.Manager()
    manage_d = manage.dict()
    manage_l = manage.list()

    #定義兩個進程
    l = []
    p1 = multiprocessing.Process(target = Proceedataget,args=(q,child_conn,parent_event,child_event,manage_d,manage_l))
    p1.start()
    l.append(p1)
    p2 = multiprocessing.Process(target = Proceedataput,args=(q,parent_conn,parent_event,child_event,manage_d,manage_l))
    p2.start()
    l.append(p2)

    #等待進程執行完畢
    for p_list in l:
        p_list.join()

    end_time = time.time()

    print(manage_d)
    print(manage_l)

    print("Mutiple proccess cost : %d"%(end_time - start_time))
View Code

參考鏈接:https://docs.python.org/2/library/multiprocessing.html

day-4 python多進程編程知識點匯總