當你剛入職場時,不管你是用C++仍是Java甚至只是應聘運維崗位,相信你都會遇到這個問題。程序員
這是一個很基礎的問題,但又是一個很考驗人水平的問題。面試
說基礎是由於每一個學計算機的人都應該懂,進程線程是計算機的基礎概念,是每一個程序員時時刻刻都要接觸的東西。編程
但這又是一個充滿陷阱能夠無限擴展和深刻的一個問題。好比能夠從操做系統知識擴展到計算機組成原理,能夠從單線程擴展到併發編程,能夠從併發編程深刻到線程同步、線程安全、進程間通訊等等。安全
那麼咱們該如何回答好這個問題呢?網絡
既然要談區別,那麼首先須要理解什麼是進程和線程。多線程
以前,我讀到一篇材料,發現有一個很好的類比,能夠把它們解釋地清晰易懂。併發
1.計算機的核心是CPU,它承擔了全部的計算任務。它就像一座工廠,時刻在運行。運維
2.假定工廠的電力有限,一次只能供給一個車間使用。也就是說,一個車間開工的時候,其餘車間都必須停工。背後的含義就是,單個CPU一次只能運行一個任務。高併發
3.進程就比如工廠的車間,它表明CPU所能處理的單個任務。任一時刻,CPU老是運行一個進程,其餘進程處於非運行狀態。spa
4.一個車間裏,能夠有不少工人。他們協同完成一個任務。
5.線程就比如車間裏的工人。一個進程能夠包括多個線程。
6.車間的空間是工人們共享的,好比許多房間是每一個工人均可以進出的。這象徵一個進程的內存空間是共享的,每一個線程均可以使用這些共享內存。
7.但是,每間房間的大小不一樣,有些房間最多隻能容納一我的,好比廁所。裏面有人的時候,其餘人就不能進去了。這表明一個線程使用某些共享內存時,其餘線程必須等它結束,才能使用這一塊內存。
8.一個防止他人進入的簡單方法,就是門口加一把鎖。先到的人鎖上門,後到的人看到上鎖,就在門口排隊,等鎖打開再進去。這就叫"互斥鎖"(Mutual exclusion,縮寫 Mutex),防止多個線程同時讀寫某一塊內存區域。
9.還有些房間,能夠同時容納n我的,好比廚房。也就是說,若是人數大於n,多出來的人只能在外面等着。這比如某些內存區域,只能供給固定數目的線程使用。
10.這時的解決方法,就是在門口掛n把鑰匙。進去的人就取一把鑰匙,出來時再把鑰匙掛回原處。後到的人發現鑰匙架空了,就知道必須在門口排隊等着了。這種作法叫作"信號量"(Semaphore),用來保證多個線程不會互相沖突。
不難看出,mutex是semaphore的一種特殊狀況(n=1時)。也就是說,徹底能夠用後者替代前者。可是,由於mutex較爲簡單,且效率高,因此在必須保證資源獨佔的狀況下,仍是採用這種設計。
11.操做系統的設計,所以能夠歸結爲三點:
(1)以多進程形式,容許多個任務同時運行;
(2)以多線程形式,容許單個任務分紅不一樣的部分運行;
(3)提供協調機制,一方面防止進程之間和線程之間產生衝突,另外一方面容許進程之間和線程之間共享資源。
這個類比能夠很形象的說明進程與線程的區別。
固然面試的時候你不可能說上這一堆,面試官估計要跟你急,時間寶貴,咱們須要用最精簡的語言說出二者的概念以及區別。
你能夠這樣分點回答(面試時須要邏輯條理清晰、語言簡潔、直中要害):
(1)進程
進程是程序的一次執行過程,是一個動態概念,是程序在執行過程當中分配和管理資源的基本單位,每個進程都有一個本身的地址空間,至少有 5 種基本狀態,它們是:初始態,執行態,等待狀態,就緒狀態,終止狀態。
(2)線程
線程是CPU調度和分派的基本單位,它可與同屬一個進程的其餘的線程共享進程所擁有的所有資源。
(3)聯繫
線程是進程的一部分,一個線程只能屬於一個進程,而一個進程能夠有多個線程,但至少有一個線程。
(4)區別:理解它們的差異,我從資源使用的角度出發。(所謂的資源就是計算機裏的中央處理器,內存,文件,網絡等等)
根本區別:進程是操做系統資源分配的基本單位,而線程是任務調度和執行的基本單位
在開銷方面:每一個進程都有獨立的代碼和數據空間(程序上下文),程序之間的切換會有較大的開銷;線程能夠看作輕量級的進程,同一類線程共享代碼和數據空間,每一個線程都有本身獨立的運行棧和程序計數器(PC),線程之間切換的開銷小。
所處環境:在操做系統中能同時運行多個進程(程序);而在同一個進程(程序)中有多個線程同時執行(經過CPU調度,在每一個時間片中只有一個線程執行)
內存分配方面:系統在運行的時候會爲每一個進程分配不一樣的內存空間;而對線程而言,除了CPU外,系統不會爲線程分配內存(線程所使用的資源來自其所屬進程的資源),線程組之間只能共享資源。
包含關係:沒有線程的進程能夠看作是單線程的,若是一個進程內有多個線程,則執行過程不是一條線的,而是多條線(線程)共同完成的;線程是進程的一部分,因此線程也被稱爲輕權進程或者輕量級進程。
擴展閱讀
一、爲何須要設計線程?
在傳統進程模型中,進程的內涵可分爲下面兩個方面:
既然是兩個獨立的功能,可不能夠把它們分離呢?這就出現了線程(thread)的概念:
那麼執行與調度的基本單位是線程,這樣設置有什麼好處?
計算機操做系統裏面有兩個重要概念:併發和隔離。
併發是爲了儘可能讓硬件利用率高,線程是爲了在系統層面作到併發。線程上下文切換效率比進程上下文切換會高不少,這樣能夠提升併發效率。
隔離也是併發以後要解決的重要問題,計算機的資源通常是共享的,隔離要能保障崩潰了這些資源可以被回收,不影響其餘代碼的使用。因此說一個操做系統只有線程沒有進程也是能夠的,只是這樣的系統會常常崩潰而已,操做系統剛開始發展的時候和這種情形很像。
因此:線程和併發有關係,進程和隔離有關係。線程基本是爲了代碼併發執行引入的概念,由於要分配cpu時間片,暫停後再恢復要可以繼續和沒暫停同樣繼續執行;進程至關於一堆線程加上線程執行過程當中申請的資源,一旦掛了,這些資源都要能回收,不影響其餘程序。