實際上,線程和進程的區(qū)別,在學OS時必然是學習過的,所缺的不過是一些總結(jié)。
1. 進程
進程(process)是計算機中已運行程序的實體。在面向線程設(shè)計的系統(tǒng)中,進程本身不是基本運行單位,而是線程的容器。程序本身只是指令、數(shù)據(jù)及其組織形式的描述,進程才是程序(那些指令和數(shù)據(jù))的真正運行實例。若干進程有可能與同一個程序相關(guān)系,且每個進程皆可以同步(循序)或異步(平行)的方式獨立運行?,F(xiàn)代計算機系統(tǒng)可在同一段時間內(nèi)以進程的形式將多個程序加載到存儲器中,并借由時間共享(或稱時分復(fù)用),以在一個處理器上表現(xiàn)出同時(平行性)運行的感覺。同樣的,使用多線程技術(shù)(多線程即每一個線程都代表一個進程內(nèi)的一個獨立執(zhí)行上下文)的操作系統(tǒng)或計算機架構(gòu),同樣程序的平行線程,可在多CPU主機或網(wǎng)絡(luò)上真正同時運行(在不同的CPU上)。
2. 線程
線程(thread)是程序執(zhí)行流的最小單元。一個標準的線程由線程ID,當前指令指針(PC),寄存器集合和堆棧組成。另外,線程是進程中的一個實體,是被系統(tǒng)獨立調(diào)度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。一個線程可以創(chuàng)建和撤消另一個線程,同一進程中的多個線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約,致使線程在運行中呈現(xiàn)出間斷性。線程也有就緒、阻塞和運行三種基本狀態(tài)。就緒狀態(tài)是指線程具備運行的所有條件,邏輯上可以運行,在等待處理機;運行狀態(tài)是指線程占有處理機正在運行;阻塞狀態(tài)是指線程在等待一個事件(如某個信號量),邏輯上不可執(zhí)行。每一個程序都至少有一個線程,若程序只有一個線程,那就是程序本身。
3. 進程與線程
我們可以總結(jié)出以下幾條區(qū)別:
- 尺度:進程是線程的容器,線程是程序執(zhí)行的最小單元。 一個程序至少有一個進程,一個進程至少有一個線程。線程的劃分尺度小于進程。
- 執(zhí)行:進程往往有獨立的運行入口,順序執(zhí)行序列,獨立的運行出口。線程不能獨立執(zhí)行,必須依存于應(yīng)用程序,由應(yīng)用程序來進行線程控制。
- 資源:進程和線程最主要的區(qū)別是他們是不同的操作系統(tǒng)資源管理方式。
- 進程有獨立的地址空間,一個進程在崩潰后,在保護模式下不會對其他進程產(chǎn)生影響。而線程只是一個進程中的不同執(zhí)行路徑,線程有自己獨立的棧和局部變量,但線程之間沒有獨立的地址空間(參見Java基礎(chǔ):Java虛擬機(JVM)),一個線程死掉往往導致整個進程死掉,所以多進程程序要比多線程程序健壯,但在進程切換時,資源消耗較大,效率要差一些。
- 對于一些要求同時進行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進程。
4. 多進程與多線程對比
- 數(shù)據(jù)共享性:多進程共享依賴復(fù)雜的進程間通信;多線程數(shù)據(jù)共享因共享進程數(shù)據(jù)而十分簡單。
- 數(shù)據(jù)同步:多進程數(shù)據(jù)分開,同步簡單;多線程數(shù)據(jù)同步復(fù)雜。
- 資源消耗:多進程占用CPU,內(nèi)存多;多線程占用CPU,內(nèi)存小。
- 創(chuàng)建銷毀切換:多進程復(fù)雜;多線程簡單。
- 編程:多進程簡單;多線程復(fù)雜。
- 可靠性:多進程不進行進程間通信的話,進程間不會互相影響;多線程一個線程掛掉將導致整個進程掛掉。
- 分布式:多進程適合多機分布式,擴展方便;多線程適合多核分布式。
5. Java多進程與多線程
5.1. Java多進程
我們常常去講多線程開發(fā),但是很少去講多進程。
對于Java而言,所有的Java程序都是在JVM中運行,而在JVM內(nèi)部,程序的運行是通過多線程實現(xiàn)的。每當用戶啟動一個Java應(yīng)用程序,就啟用了一個Java進程。
Java的多進程通信可以使用管道或者socket。
5.2. Java多線程
正如在文章JVM里講過那樣,Java的多線程是和操作系統(tǒng)的線程進行映射的。實際上Thread類的大部分api和Java其他api不同,其關(guān)鍵方法是native方法,換言之,Java的多線程的實現(xiàn)有賴于操作系統(tǒng)本身的多線程實現(xiàn),操作系統(tǒng)的線程模型很大程度的決定了Java虛擬機的映射。
綜上,Java本身運行在JVM虛擬機中,而Java的多進程通信又只能依賴于管道和socket,在絕大多情況下,應(yīng)該考慮的是多線程而非多進程。