1. 程式人生 > >Python multiprocessing庫使用手記(引子)

Python multiprocessing庫使用手記(引子)

前段時間在做的一個Python專案,需要實現一個後臺服務程式,程式流程比較複雜,而且可能經常變動,但是如果把整個流程切分成一些步驟,每個步 驟有自己的輸入輸出和處理。只要將他們的輸入輸出接在一起,進行不同的組合就可以實現常見的流程變動。

使用多程序的原因是考慮到Python的全域性直譯器鎖(Global Interceptor Lock , GIL)。由於GIL的存在,在CPU密集型的程式當中,使用多執行緒並不能有效地利用多核CPU的優勢,因為一個直譯器在同一時刻只會有一個執行緒在執行。 要想盡可能利用多核CPU併發,多程序是必需的。

引入多程序就帶來幾個問題:首先是這種設計方案需要一個類似於UNIX Pipe的底層結構,說的更確切一點就是message queue,操作類似於Python的Queue.Queue。另一個問題就是需要一個程序間資訊共享的基礎設施。

先說Queue,這個Queue需要滿足下面一些需求,優先順序遞減:

  • 輕量 – 不需要依賴資料庫等比較重型的程式。代價就是丟點東西沒關係;
  • 跨程序 – 讀端和寫端可以不在一個程序當中;
  • 支援多進多出 – 讀端和寫端都要支援多個程序;
  • 穩定和高效 – 這個就不用多說了吧;
  • 有Python的API,再不濟要有C的API可以讓我寫Python的binding。

另外是程序間共享的設施,系統shm是迫不得已使用的,因為要自己處理Pickling和Unpickling,以及一些雜七雜八的競爭條件問題。 有建構在上面的現成的庫最好。

最終出於輕量的考慮,選定了Python的multiprocessing

庫,而沒有用IPC MQ 或 RabbitMQ 。這個庫在Python2.6被引入到標準庫當中,有為2.5提供的backport 。因為我們的系統使用的是2.5版本,因此我們使用的其實是2.5的backport。這個 實現除了一些細枝末節的地方之外,核心實現和2.6標準庫當中是完全一樣的。

在使用過程當中,遇到了挺多的問題,在這裡一一記錄。