愛伊米

執行緒、程序、多執行緒、多程序和多工有啥關係?

可能學習作業系統開發的讀者都聽說過這些專業名詞,但又多少人理解了?

首先,從定義開始,先看一下教科書上程序和執行緒定義:

程序:

資源分配的最小單位。

執行緒:

程式執行的最小單位。

1

程序

程序是程式執行時的一個例項,即它是程式已經執行到課中程度的資料結構的彙集。從核心的觀點看,程序的目的就是擔當分配系統資源(CPU時間、記憶體等)的基本單位。

舉例說明程序:

想象一位有一手好廚藝的計算機科學家正在為他的女兒烘製生日蛋糕,他有做生日蛋糕的食譜,廚房裡有所需的原料:麵粉、雞蛋、糖、香草汁等。在這個比喻中,做蛋糕的食譜就是程式(即用適當形式描述的演算法)計算機科學家就是處理器(CPU),而做蛋糕的各種原料就是輸入資料。

程序就是廚師閱讀食譜、取來各種原料以及烘製蛋糕等一系列動作的總和。現在假設計算機科學家的兒子哭著跑了進來,說他的頭被一隻蜜蜂蟄了。計算機科學家就記錄下他照著食譜做到哪兒了(儲存程序的當前狀態),然後拿出一本急救手冊,按照其中的指示處理蟄傷。這裡,我們看到處理機制是從一個程序(做蛋糕)切換到另一個高優先順序的程序(實施醫療救治),每個程序擁有各自的程式(食譜和急救手冊)。當蜜蜂蟄傷處理完之後,這位計算機科學家又回來做蛋糕,從他離開時的那一步繼續做下去。

2

執行緒

執行緒是CPU排程的最小單位(程式執行流的最小單元),它被包含在程序之中,是程序中的實際運作單元。一條執行緒是程序中一個單一順序的控制流,一個程序中可以併發多個執行緒,每條執行緒並行執行不同的任務。

一個標準的執行緒有執行緒ID、當前指令指標(PC),暫存器集合和堆疊組成。另外,執行緒是程序中的一個實體,是被系統獨立排程和分派的基本單元,執行緒自己不擁有系統資源,只擁有一點兒在執行中必不可少的資源,但它可與同屬一個程序的其他執行緒共享程序所擁有的全部資源。一個執行緒可以建立和撤銷另一個執行緒,同一程序中的多個執行緒之間可以併發執行。由於執行緒之間的相互制約,致使執行緒在執行中呈現處間斷性。

執行緒也有就緒、阻塞和執行三種基本狀態。就緒狀態是指執行緒具備執行的所有條件,邏輯上可以執行,在等待處理機;執行狀態是指執行緒佔有處理機正在執行;阻塞狀態是指執行緒在等待一個事件(如某個訊號量),邏輯上不可執行。每一個程式都至少有一個執行緒,若程式只有一個執行緒,那就是程式本身。

舉例說明執行緒:

假設,一個文字程式,需要接受鍵盤輸入,將內容顯示在螢幕上,還需要儲存資訊到硬碟中。若只有一個程序,勢必造成同一時間只能幹一樣事的尷尬(當儲存時,就不能透過鍵盤輸入內容)。若有多個程序,每個程序負責一個任務,程序A負責接收鍵盤輸入的任務,程序B負責將內容顯示在螢幕上的任務,程序C負責儲存內容到硬碟中的任務。這裡程序A,B,C間的協作涉及到了程序通訊問題,而且有共同都需要擁有的東西——-文字內容,不停的切換造成效能上的損失。若有一種機制,可以使任務A,B,C共享資源,這樣上下文切換所需要儲存和恢復的內容就少了,同時又可以減少通訊所帶來的效能損耗,那就好了。這種機制就是執行緒。

總的來說:

程序有獨立的地址空間,執行緒沒有單獨的地址空間(同一程序內的執行緒共享程序的地址空間)。

3

多程序

程序是程式在計算機上的一次執行活動,當你執行一個程式,你就啟動了一個程序。顯然,程式是死的(靜態的),程序是活的(動態的)。

程序可以分為系統程序和使用者程序,凡是用於完成作業系統的各種功能的程序就是系統程序,它們就是處於執行狀態下的作業系統本身;所有由使用者啟動的程序都是使用者程序。程序是作業系統進行資源分配的單位。程序又被細化為執行緒,也就是一個程序下有多個能獨立執行的更小的單位。在同一個時間裡,同一個計算機系統中如果允許兩個或兩個以上的程序處於執行狀態,這便是多工。現代的作業系統幾乎都是多工作業系統,能夠同時管理多個程序的執行。

多工帶來的好處是明顯的,比如你可以邊聽網易雲音樂,一邊上網,與此同時甚至可以將下載的文件打印出來,而這些任務之間絲毫不會相互干擾。那麼這裡就涉及到並行的問題,俗話說,一心不能二用,這對計算機也一樣,原則上一個CPU只能分配給一個程序,以便執行這個程序。我們通常使用的計算機中只有一個CPU,也就是說只有一顆心,要讓它一心多用,同時執行多個程序,就必須使用併發技術。實現併發技術相當複雜,最容易理解的是“時間片輪轉程序排程演算法”,它的思想簡單介紹如下:在作業系統的管理下,所有正在執行的程序輪流使用CPU,每個程序允許佔用CPU的時間非常短(比如10毫秒),這樣使用者根本感覺不出來 CPU是在輪流為多個程序服務,就好像所有的程序都在不間斷地執行一樣。

但實際上在任何一個時間內有且僅有一個程序佔有CPU。如果一臺計算機有多個CPU,情況就不同了,如果程序數小於CPU數,則不同的程序可以分配給不同的CPU來執行,這樣,多個程序就是真正同時執行的,這便是並行。

並行處理(Parallel Processing)是計算機系統中能同時執行兩個或更多個處理的一種計算方法。並行處理可同時工作於同一程式的不同方面。並行處理的主要目的是節省大型和複雜問題的解決時間。併發處理(concurrency Processing):指一個時間段中有幾個程式都處於已啟動執行到執行完畢之間,且這幾個程式都是在同一個處理機(CPU)上執行,但任一個時刻點上只有一個程式在處理機(CPU)上執行

併發的關鍵是你有處理多個任務的能力,不一定要同時。並行的關鍵是你有同時處理多個任務的能力。所以說,並行是併發的子集。

執行緒、程序、多執行緒、多程序和多工有啥關係?

4

多執行緒

執行緒是程式中一個單一的順序控制流程。程序內一個相對獨立的、可排程的執行單元,是系統獨立排程和分派CPU的基本單元。在單一程式中同時執行多個想成完成不同的工作,稱為多執行緒。

多執行緒是為了使得多個執行緒並行的工作以完成多項任務,以提高系統的效率。執行緒是在同一時間需要完成多項任務的時候被實現的。打個比方:

多程序是立體交通系統(近似於立交橋),雖然造價高,上坡下坡多耗點油,但是不堵車。

多執行緒是平面交通系統,造價低,但紅綠燈太多,老堵車。

5

執行緒與程序的關係

(1)一個執行緒只能屬於一個程序,而一個程序可以有多個執行緒,但至少有一個執行緒;(2)資源分配給程序,同一程序內的所有執行緒共享該程序的所有資源;(3)執行緒在執行過程中需要協作同步。不同程序中的執行緒之間要利用訊息通訊的方法實現同步;(4)處理機分配給執行緒,即真正在處理機上執行的是執行緒;(5)執行緒是程序的一個執行單元,也是程序內的可呼叫實體。

執行緒、程序、多執行緒、多程序和多工有啥關係?

6

執行緒和程序的區別

(1)執行緒共享記憶體空間;程序的記憶體是獨立的;(2)同一個程序的執行緒之間可以直接交流;兩個程序想通訊,必須透過一箇中間代理來實現;(3)建立新程序很簡單;建立新程序需要對其父程序進行一個克隆;(4)一個執行緒可以控制和操作同一程序裡的其他執行緒;但是程序只能操作子程序;(5)改變注執行緒(如優先權),可能會影響其他執行緒;改變父程序,不影響子程序。(6)排程:執行緒作為分配和排程的基本單位,程序作為擁有資源的基本單位(7)併發性:不進程序之間可以併發執行,同一程序內的執行緒也可以併發執行(8)擁有資源:程序是擁有資源的一個獨立單位,執行緒不擁有系統資源,但是可以訪問隸屬於程序的系統資源(9)系統開銷:在建立和撤銷程序的時候,系統都要分配和回收資源,導致系統的明顯大於建立和撤銷執行緒時的開銷。但程序有獨立的地址空間,程序崩潰後,在保護模式的下不會對其他程序造成影響,而執行緒只是程序中的不同執行路徑。執行緒有自己的堆疊和區域性變數,但執行緒之間沒有獨立的地址空間,一個執行緒死後就等於整個程序死掉,所以多程序程式要比多執行緒程式健壯,但是在程序切換的時候消耗的資源較大,效率差。根本區別就一點:用多程序每個程序有自己的地址空間(address space),執行緒則共享地址空間。

總結:多執行緒執行效率高;  多程序耗資源,安全。

7

程序的優缺點

7.1 程序的優點

1)順序程式的特點:具有封閉性和可再現性;2)程式的併發執行和資源共享。多道程式設計出現後,實現了程式的併發執行和資源共享,提高了系統的效率和系統的資源利用率。

7.2 程序的缺點

作業系統排程切換多個執行緒要比切換排程程序在速度上快的多。而且程序間記憶體無法共享,通訊也比較麻煩。執行緒之間由於共享程序記憶體空間,所以交換資料非常方便;在建立或撤消程序時,由於系統都要為之分配和回收資源,導致系統的開銷明顯大於建立或撤消執行緒時的開銷。

8

執行緒的優缺點

8.1 執行緒的優點

1)它是一種非常“節儉”的多工操作方式。在Linux系統下,啟動一個新的程序必須分配給它獨立的地址空間,建立眾多的資料表來維護它的程式碼 段、堆疊段和資料段,這是一種“昂貴”的多工工作方式。而運行於一個程序中的多個執行緒,它們彼此之間使用相同的地址空間,共享大部分資料,啟動一個執行緒 所花費的空間遠遠小於啟動一個程序所花費的空間,而且,執行緒間彼此切換所需的時間也遠遠小於程序間切換所需要的時間。當然,在具體的系統上,這個資料可能 會有較大的區別;2)執行緒間方便的通訊機制,由於同一程序下的執行緒之間共享資料空間,所以一個執行緒的資料可以直接為其它執行緒所用,這不僅快捷,而且方便;3)使多CPU系統更加有效。作業系統會保證當執行緒數不大於CPU數目時,不同的執行緒運行於不同的CPU上;4)改善程式結構。一個既長又複雜的程序可以考慮分為多個執行緒,成為幾個獨立或半獨立的執行部分,這樣的程式會利於理解和修改。

8.2 執行緒的缺點

1)排程時, 要儲存執行緒狀態,頻繁排程,需要佔用大量的機時;2)程式設計上容易出錯(執行緒同步問題)。

9

多執行緒的優缺點

9.1 多執行緒的優點

1)無需跨程序邊界;程式邏輯和控制方式簡單;2)所有執行緒可以直接共享記憶體和變數等;3)執行緒方式消耗的總資源比程序方式好。

9.2 多執行緒的缺點

1)每個執行緒與主程式共用地址空間,受限於2GB地址空間;2)執行緒之間的同步和加鎖控制比較麻煩;一個執行緒的崩潰可能影響到整個程式的穩定性;3)到達一定的執行緒數程度後,即使再增加CPU也無法提高效能,例如Windows Server 2003,大約是1500個左右的執行緒數就快到極限了(執行緒堆疊設定為1M),如果設定執行緒堆疊為2M,還達不到1500個執行緒總數;4)執行緒能夠提高的總效能有限,而且執行緒多了之後,執行緒本身的排程也是一個麻煩事兒,需要消耗較多的CPU 。

10

多程序的優缺點

10.1 多程序的優點

1)每個程序互相獨立,不影響主程式的穩定性,子程序崩潰沒關係;2)透過增加CPU,就可以容易擴充效能;3)可以儘量減少執行緒加鎖/解鎖的影響,極大提高效能,就算是執行緒執行的模組演算法效率低也沒關係;4)每個子程序都有2GB地址空間和相關資源,總體能夠達到的效能上限非常大。

10.2 多程序的缺點

1)邏輯控制複雜,需要和主程式互動;2)需要跨程序邊界,如果有大資料量傳送,就不太好,適合小資料量傳送、密集運算 多程序排程開銷比較大。 總結:最好是多程序和多執行緒結合,即根據實際的需要,每個CPU開啟一個子程序,這個子程序開啟多執行緒可以為若干同類型的資料進行處理。當然你也可以利用多執行緒+CPU+輪詢方式來解決問題……方法和手段是多樣的,關鍵是自己看起來實現方便有能夠滿足要求,代價也合適。 按照多個不同的維度(類別),來看看多執行緒和多程序的對比(注:因為是感性的比較,因此都是相對的,不是說一個好得不得了,另外一個差的無法忍受)。

執行緒、程序、多執行緒、多程序和多工有啥關係?

其實沒有絕對的好與壞,只有哪個更加合適的問題。我們來看實際應用中究竟如何判斷更加合適。1)需要頻繁建立銷燬的優先用執行緒這種原則最常見的應用就是Web伺服器了,來一個連線建立一個執行緒,斷了就銷燬執行緒,要是用程序,建立和銷燬的代價是很難承受的 2)需要進行大量計算的優先使用執行緒所謂大量計算,當然就是要耗費很多CPU,切換頻繁了,這種情況下執行緒是最合適的。這種原則最常見的是影象處理、演算法處理。 3)強相關的處理用執行緒,弱相關的處理用程序什麼叫強相關、弱相關?理論上很難定義,給個簡單的例子就明白了。一般的Server需要完成如下任務:訊息收發、訊息處理。“訊息收發”和“訊息處理”就是弱相關的任務,而“訊息處理”裡面可能又分為“訊息解碼”、“業務處理”,這兩個任務相對來說相關性就要強多了。因此“訊息收發”和“訊息處理”可以分程序設計,“訊息解碼”、“業務處理”可以分執行緒設計。當然這種劃分方式不是一成不變的,也可以根據實際情況進行調整。 4)可能要擴充套件到多機分佈的用程序,多核分佈的用執行緒 5)都滿足需求的情況下,用你最熟悉、最拿手的方式至於“資料共享、同步”、“程式設計、除錯”、“可靠性”這幾個維度的所謂的“複雜、簡單”應該怎麼取捨,我只能說:沒有明確的選擇方法。但我可以告訴你一個選擇原則:如果多程序和多執行緒都能夠滿足要求,那麼選擇你最熟悉、最拿手的那個。需要提醒的是:雖然我給了這麼多的選擇原則,但實際應用中基本上都是“程序+執行緒”的結合方式,千萬不要真的陷入一種非此即彼的誤區。

11

多工(多程序)

現代作業系統比如Mac OS X,UNIX,Linux,Windows等,都是支援“多工”的作業系統。

什麼叫“多工”呢?簡單地說,就是作業系統可以同時執行多個任務。打個比方,你一邊在用瀏覽器上網,一邊在聽MP3,一邊在用Word寫論文,這就是多工,至少同時有3個任務正在執行。還有很多工悄悄地在後臺同時執行著,只是桌面上沒有顯示而已。

現在,多核CPU已經非常普及了,但是,即使過去的單核CPU,也可以執行多工。由於CPU執行程式碼都是順序執行的,那麼,單核CPU是怎麼執行多工的呢?

其實作業系統輪流讓各個任務交替執行,任務1執行0。01秒,切換到任務2,任務2執行0。01秒,再切換到任務3,執行0。01秒……這樣反覆執行下去。表面上看,每個任務都是交替執行的,但是,由於CPU的執行速度實在是太快了,我們感覺就像所有任務都在同時執行一樣。

真正的並行執行多工只能在多核CPU上實現,但是,由於任務數量遠遠多於CPU的核心數量,所以,作業系統也會自動把很多工輪流排程到每個核心上執行。

對於作業系統來說,一個任務就是一個程序(Process),比如開啟一個瀏覽器就是啟動一個瀏覽器程序,開啟一個記事本就啟動了一個記事本程序,開啟兩個記事本就啟動了兩個記事本程序,開啟一個Word就啟動了一個Word程序。

有些程序還不止同時幹一件事,比如Word,它可以同時進行打字、拼寫檢查、列印等事情。在一個程序內部,要同時幹多件事,就需要同時執行多個“子任務”,我們把程序內的這些 “子任務” 稱為執行緒(Thread)。

由於每個程序至少要幹一件事,所以,一個程序至少有一個執行緒。當然,像Word這種複雜的程序可以有多個執行緒,多個執行緒可以同時執行,多執行緒的執行方式和多程序是一樣的,也是由作業系統在多個執行緒之間快速切換,讓每個執行緒都短暫地交替執行,看起來就像同時執行一樣。當然,真正地同時執行多執行緒需要多核CPU才可能實現。