16. python多進程總結

1. 啟動多進程的方式

  1. os.fork 只支持Unix,不支持windows
  2. 使用multiprocessing模塊: 創(chuàng)建Process的實例,傳入任務執(zhí)行函數(shù)作為參數(shù)
  3. 使用multiprocessing模塊: 派生Process的子類,重寫run方法
  4. 使用進程池Pool

2. 啟動多進程注意

  1. multiprocessing是基于fork(),因為windows沒有fork()函數(shù)但是可以通過在__main__中啟動子進程來規(guī)避
  2. multiprocessing創(chuàng)建子進程時會在子進程空間中復制一份主進程的代碼,全局變量在多個子進程之間不共享
  3. 多進程之間數(shù)據(jù)是隔離的

3. python守護進程

  1. 正常情況下,如果主進程代碼執(zhí)行完成,但是子進程還沒有執(zhí)行完成,則程序還不會退出,而是繼續(xù)等待子進程。
  2. 當要實現(xiàn)子進程要隨主進程結束而結束時就可以設置守護進程。
  3. 設置守護進程的方式是在start()之前設置 daemon = True
  4. p.terminate() 是終止一個進程,該代碼執(zhí)行后進程不是立刻結束,CPU還有一個調(diào)度的過程此時用p.is_alive()檢查發(fā)現(xiàn)結果為True,time.sleep() 一秒后再用p.is_alive()檢查會發(fā)現(xiàn)結果為False

4. python多進程鎖

  1. Lock類與RLock類相同:由于進程之間隨機調(diào)度:某進程可能執(zhí)行n條后,CPU接著執(zhí)行其他進程。為了多個進程同時操作一個內(nèi)存中的資源時不產(chǎn)生混亂,我們使用鎖。
  2. Lock類與RLock類的區(qū)別:無論是Lock還是RLock,提供的方法都非常簡單,acquire和release。但是Lock和RLock的區(qū)別是什么呢?RLock允許在同一線程中被多次acquire。而Lock卻不允許這種情況。注意:如果使用RLock,那么acquire和release必須成對出現(xiàn),即調(diào)用了n次acquire,必須調(diào)用n次的release才能真正釋放所占用的鎖。

5. python多進程信號量-Semaphore

  1. 信號量Semaphore是一個計數(shù)器,控制對公共資源或者臨界區(qū)域的訪問量,信號量可以指定同時訪問資源或者進入臨界區(qū)域的進程數(shù)。每次有一個進程獲得信號量時,計數(shù)器-1,若計數(shù)器為0時,其他進程就停止訪問信號量,一直阻塞直到其他進程釋放信號量。

6.python多進程事件

  1. 多進程中的事件Event-進程之間的狀態(tài)標記通信,它是由進程設置的信號標志,如果信號標志為真,則其他進程等待直到信號解除
  2. Event對象實現(xiàn)了簡單的進程通信機制,它提供了設置信號,清除信號,等待等用于實現(xiàn)進程間通信的方法
  3. Event對象創(chuàng)建時默認信號設置為False。False時會在wait()處阻塞,True時不阻塞

7. python多進程之隊列

  1. IPC(Inter-Process Communication)進程之間通信
  2. 隊列先進先出
  3. Queue()實例化是可以傳一個參數(shù)代表隊列上限,如果不傳或傳負數(shù)都表示隊列沒有限制。
  4. 當隊列容量不夠時會阻塞
  5. Queue可以創(chuàng)建共享的進程隊列,Queue是多進程安全的隊列,可以使用Queue實現(xiàn)多進程之間的數(shù)據(jù)傳遞

8. python多進程之JoinableQueue

  1. JoinableQueue 與Queue一樣也是multiprocessing模塊中的一個類,也可以用于創(chuàng)建進程隊列。
  2. JoinableQueue 創(chuàng)建可連接的共享進程隊列,隊列允許隊列的消費者通知生產(chǎn)者,隊列數(shù)據(jù)已被成功處理完成。通知過程是使用共享的信號和條件變量來實現(xiàn)的。

9. python多進程之Pipe

  1. Pipe返回2個連接對象(conn1, conn2),代表管道的兩端,默認是雙向通信的,即conn1和conn2都可以收發(fā)消息。
  2. Pipe是數(shù)據(jù)不安全的,所以如果是多個進程之間同時收發(fā)消息時,需要自己加鎖以達到數(shù)據(jù)安全。
  3. 如果是生產(chǎn)者或消費者中都沒有使用管道的某個端點,就應將它關閉。這也說明了為何在生產(chǎn)者中關閉了管道的輸出端,在消費者中關閉管道的輸入端。如果忘記執(zhí)行這些步驟,程序可能在消費者中的recv()操作上掛起。
  4. 管道是由操作系統(tǒng)進行引用計數(shù)的,必須在所有進程中關閉管道后才能生成EOFError異常。因此,在生產(chǎn)者中關閉管道不會有任何效果,除非消費者也關閉了相同的管道端點

10. python多進程之Pool

  1. 在程序實際處理問題過程中,忙時會有成千上萬的任務需要被執(zhí)行,閑時可能只有零星任務。那么在成千上萬個任務需要被執(zhí)行的時候,我們就需要去創(chuàng)建成千上萬個進程么?
  2. 首先,創(chuàng)建進程需要消耗時間,銷毀進程也需要消耗時間。第二即便開啟了成千上萬的進程,操作系統(tǒng)也不能讓他們同時執(zhí)行,這樣反而會影響程序的效率。因此我們不能無限制的根據(jù)任務開啟或者結束進程。那么我們要怎么做呢?
  3. 這樣就引入了進程池,進程池是指定義一個進程池,在里面放上固定數(shù)量的進程,有需求來了,就拿進程池中的一個進程來處理任務,等到處理完畢,進程并不關閉,而是將進程再放回進程池中繼續(xù)等待任務。
  4. 如果有很多任務需要執(zhí)行,進程池中的進程數(shù)量不夠,任務就要等待之前的進程執(zhí)行任務完畢歸來,拿到空閑進程才能繼續(xù)執(zhí)行。也就是說,池中進程的數(shù)量是固定的,那么同一時間最多有固定數(shù)量的進程在運行。這樣不會增加操作系統(tǒng)的調(diào)度難度,還節(jié)省了開閉進程的時間,也一定程度上能夠實現(xiàn)并發(fā)效果。

11.python多進程之Manager

  1. Python中提供了強大的Manager類,專門用于實現(xiàn)多進程之間的數(shù)據(jù)共享;
  2. Manager類是數(shù)據(jù)不安全的;
  3. Mangaer類支持的類型非常多,如:value, Array, List, Dict, Queue, Lock等。
  4. Manager 類包含的常用方法和屬性與Multiprocessing中其他常用類的方法屬性一致。

12.python多進程之回調(diào)函數(shù)

  1. 需要回調(diào)函數(shù)的場景:進程池中任何一個任務一旦處理完了,就立即告知主進程:我好了額,你可以處理我的結果了。主進程則調(diào)用一個函數(shù)去處理該結果,該函數(shù)即回調(diào)函數(shù)
  2. 我們可以把耗時間(阻塞)的任務放到進程池中,然后指定回調(diào)函數(shù)(主進程負責執(zhí)行),這樣主進程在執(zhí)行回調(diào)函數(shù)時就省去了I/O的過程,直接拿到的是任務的結果。
  3. 子進程執(zhí)行返回的結果做為回調(diào)函數(shù)的參數(shù)傳入。
  4. 回調(diào)函數(shù)是在主進程中執(zhí)行的?;卣{(diào)函數(shù)適用于子進程數(shù)多且耗時時間長的場景。
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容