Python 2.6 亮點:multiprocessing模塊

原本覺得Python 2.6只是Python 3.0的過渡版本,不會有太多的新功能。但看到這個2.6的重大改動列表,才發現本身挺落後的。在2.6中新增的multiprocessing模塊也絕對是Python 2.6的殺手級應用(PEP371文檔)。html

Multiprocessing簡單的說就是模仿threading模塊,讓在Python中使用進程和使用線程同樣方便。這個模塊並非一個新的東西,原來是pyprocessing,只是在2.6裏面被引入。但稱爲一個標準模塊以後,地位就不同了,相似於ctype、sqlite被引入標準模塊,就等於認可這些模塊提供的功能具備普遍的需求。而multiprocessing之因此能躋身標準模塊的行列,仍是由於GIL。GIL讓python的解析器更容易寫,但也讓Python中的線程有點雞肋的感受。事實上能受益於Python的線程模式的只有處於IO瓶頸的程序或者以圖形爲主程序。而對於渴求CPU的程序,線程不但不能讓程序更快,反而讓程序更慢。這能夠說是Python的問題,也能夠說是線程自己的問題。線程最大的罪惡無非是破壞了進程的隔離度,給程序員帶來了便捷也帶來了災難,這方面有點像C。而面對線程的缺點,Python解釋器想保護本身只有兩條路:一是使用相似於GIL的技術,二是使用更復雜的細粒度同步技術。對於一個並不是面向於企業級市場(至少不是主要目的)的腳本語言,採用前者更符合現實要求:大部分Python程序都是單進程單線程的,大部分C庫都不是線程安全的,而一個細粒度鎖的解析器須要很是大的精力才能達到差很少的單線程性能,一般還帶有一些隱藏得很深的bug。(若是再廣義一點,其實還有第三條路,就是採用微進程+多線程解析器的技術,相似於Erlang所採用的。但這個技術主要問題在於擴展比較難寫,難以跟已經存在的大量庫和應用接口)但隨着Python近年來的進一步流行,人們對Python的要求也愈來愈高,而GIL也顯得有些阻礙你們發揮;而多核CPU的出現,更讓Python有點難堪。此次multiprocessing進入標準模塊,也算是對這個疑問的回答。python

Multiprocessing到底帶來了什麼?簡單的說,是回到了多線程以前的老路上,多進程模式。多進程模式不是一個比多線程低級的模式。它的高隔離度帶來了不少便利:安全,編碼簡單,能夠透明的在集羣上運行。並且,通過多年的發展,進程並不比線程耗費更多資源;在Linux上,進程和線程不管在建立速度和調度上,都已經沒有明顯差距。剛剛發佈的google chrome瀏覽器就採用了多進程的模式。但對於以前的Python來講,阻礙用戶使用多進程模式的問題有障礙有兩個:1,平臺兼容問題;2,沒有足夠強大的IPC支持。平臺兼容問題出在Windows上。Windows上沒有相似fork的系統調用,也不能徹底模擬fork調用,讓使用多進程模型編程多少有些擔憂。IPC的問題更嚴重。操做系統通常提供不少IPC模式,從簡單的Pipe到複雜的shm和socket。雖然Python也提供這些IPC方法,但這些IPC都是基於字節流或字節塊的,而Python的基本單位是對象;這個差別讓多進程代碼中難免出現一些處理底層數據交流的代碼,容易出錯,也複雜。Miltiprocessing主要解決的就是這兩個問題,儘可能磨平平臺間的差別(固然,不能徹底磨平,詳見multiprocessing的文檔),也提供了更高層的API讓使用者能忽略掉底層的IPC問題。在提供的IPC API上主要分兩個部分。第一部分是對操做系統提供的IPC方法簡單包裝。好比,讓pipe能夠傳送對象,讓queue變得進程共享,甚至能夠經過共享內存共享簡單的對象。第二部分是對複雜對象提供共享支持:實現了一個簡單的RPC模型,並複雜的對象能夠在本地/遠程主機間共享。第二部分提及來有點神奇,實際上挺簡單的。Multiprocessing模塊會fork一個進程,而這個進程會監聽到某個端口;須要共享對象的進程(實際上應該說是線程,每一個線程都會有一個鏈接,固然,是你須要的時候纔會鏈接過去)鏈接到這個處理進程,經過pickle編碼發送請求,調用相應的方法,返回相應的結果;全部共享的對象都是存活在處理進程中。比較有意思的是,這個處理進程自己是使用線程來達到併發處理的目的……每一個鏈接都會單獨由一個線程來處理。處理進程怎麼解決同步問題呢?很簡單,他不一樣步,把同步的事情交給程序員去作。ios

固然,multiprocessing並非完美的。就目前來講,pickle編碼方式會是一個問題,程序員須要注意到什麼資源能夠傳輸,什麼資源不能傳輸。單獨進程處理複雜共享對象也會是一個問題,共享大量對象的時候會形成瓶頸;而簡單的多線程併發模式也多是一個瓶頸,要知道Python的線程並非那麼好。並且,試圖掩蓋網絡的真實環境讓本地和遠程進程共享對象也是頗難解決的問題,目前,處理進程忽然崩潰,會致使全部數據丟失,也會致使其餘進程不斷從新鏈接形成假死。程序員

相關文章
相關標籤/搜索