關於Python和Java的多進程多線程計算方法對比

來源:互聯網
上載者:User

標籤:大資料   並行計算   多進程   python   java   

原文請見 

關於Python和Java的多進程多線程計算方法對比

搞大資料必須要正視的一個問題就是並行計算。就像執行一件任務一樣,大夥一起同時幹,才有效率,才會很快出成果。正所謂“眾人拾柴火焰高”~

對於並行計算,有很多高大上的概念,我也不全懂。這裡就單單羅列一下我對於多進程和多線程計算的理解和總結。
在電腦中,處理一個任務,可以在一個進程中,也可以在一個線程中,確切的說,執行的話都得靠一個個線程來。在我們做某件事的時候,往往需要同時幹多個任務才能達到我們所要的效果,比如說看電影,就要讓電腦實現讓人“看”的任務,又要實現讓人“聽”的任務。電腦根據具體CPU的情況,開多個進程,而每個進程,又可以有多個線程。


先說“多進程”:

在Python中,實現多進程是比較容易的。我們可以使用multiprocessing進行進程的建立,比如說
import multiprocessing as mpp = mp.Process(target=run_proc, args=('fireling',), name='Run_procProcess')p.start()p.join()

這樣就建立了一個進程,用p表示,其中run_proc表示你用子進程啟動並執行函數。
如果覺得這樣不過癮,還可以採用進程池建立多個進程,涉及到了兩種用法:pool-apply用法和pool-map用法,本質上跟建立單個進程是一樣的。
還是要用到multiprocessing包,先建立一個進程池
p = mp.Pool()p.map(run_proc, [i for i in range(m)])p.close()p.join()

在Java中,程式都是在JVM上啟動並執行,一個JVM佔一個進程,所以多進程的概念,應該不存在。


再說“多線程”:

和多進程的思路類似,我們也可以實現對線程的建立,在Python中,使用threading包實現。比如說
import threadingt = threading.Thread(target=run_thread, args=('fireling', ), name='Run_threadThread')t.start()t.join()

這樣就建立了一個線程,用t表示,其中run_thread表示你用子線程啟動並執行函數。
但是由於多執行緒任務,往往有些變數由所有線程共用,這種變數叫全域變數,在所有線程中,這種變數只儲存一份。所以多執行緒任務,特別是對於全域變數修改的時候,我們往往要加線程鎖,保證在對某個全域變數修改的時候,只有一個線程接觸到它。
首先要先聲明線程鎖,
lock = threading.Lock()

在這些線程調用的函數定義中,我們可以加兩句話:
lock.acquire() # 擷取線程鎖xxxxxxxxxxx 此處省略若干代碼lock.release() # 釋放線程鎖

全域鎖針對的是所有線程的全域變數,那麼我們如果要處理單個線程的局部變數呢?可以用到ThreadLocal方法。
在Java中並行計算要涉及多線程。同樣的,在一個JVM進程空間中,存在多個棧來記錄多個線程的調用,但是這些線程共用堆中的對象,也就是說,對這些對象的修改,也需要加線程鎖機制。
Java中實現多線程主要有兩種方法:繼承Thread類來建立線程,並提供run()方法,或者實施Runnable介面來建立線程,並提供run()方法。
如果二者同時存在,它會首先找子類的run方法,如果子類沒有重寫run,則再找Runnable介面的run方法。下面的例子,說明了這個結論,最後輸出的是子類重寫run方法的輸出。
public class Test{public static void main(String[] args){Thread thread = new Thread(new Runnable() {@Overridepublic void run() {while(true) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Runnable1:" + Thread.currentThread().getName());//System.out.println("Runnable2:" + this.getName());}}}) {@Overridepublic void run() {while(true) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread1:" + Thread.currentThread().getName());System.out.println("Thread2:" + this.getName());}}};thread.start();}}

與Python對應的是,Java線程鎖是通過同步機制來實現的,也就是synchronized方法。同一對象的synchronized方法只能同時被一個線程調用。其他線程必須等待該線程調用結束才能運行,排除了多線程同時修改全域變數的可能。
值得一提的是,Python中對應的全域變數用關鍵字global表示,而java和C/C++中用static來表示。


關於”協程“:

Python能實現多個線程,但是實際上無法充分利用系統資源,原因在於Python存在全域鎖機制,簡單來說,就是同一時刻在一個進程中只能有一個線程對資料進行操作。所以實現並行效果,採用多進程方法,比較好。
協程在一定程度上解決了這個問題。協程機制,就是在運行某個任務的過程中,我們可以隨時中斷,去執行另一任務,也可能隨時再回來執行老任務。這在網路傳輸,IO過程中很有用,特別是對於兩個不相關的任務來說,使用協程能達到非同步執行的效果。
Java,不知道有沒有這種機制。雖然xxxx,但是Java也不錯的啦~~~在TIOBE程式設計語言熱門排行榜一直穩坐頭把交椅,這裡面,無非Android開發給了Java這個優勢。

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

關於Python和Java的多進程多線程計算方法對比

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.