幾乎所有的作業系統都支援同時執行多個任務,一個任務通常就是一個程式,每一個執行中的程式就是一個進程。當一個程式執行時,內部可能包含多個順序執行流,每一個順序執行流就是一個執行緒。
執行緒和進程
幾乎所有的作業系統都支援進程的概念,所有執行中的任務通常對應一個
進程(Process)。當一個程式進入記憶體執行時,即變成一個進程。進程是處於執行過程中的程式,並且具有一定的獨立功能。進程是系統進行資源分配和排程的一個獨立單位。
一般而言,進程包含如下三個特徵:
-
獨立性:進程是系統中獨立存在的實體,它可以擁有自己的獨立的資源,每一個進程都擁有自己的私有的地址空間。在沒有經過進程本身允許的情況下,一個使用者進程不可以直接存取其他進程的地址空間。
-
動態性:進程與程式的區別在於,程式只是一個靜態的指令集合,而進程是一個正在系統中活動的指令集合。在進程中加入了時間的概念。進程具有自己的生命週期和各種不同的狀態,在程式中是沒有這些概念的。
-
並行性:多個進程可以在單個處理器上並行執行,多個進程之間不會互相影響。
並行(Concurrency)和並行(Parallel)是兩個概念,並行指在同一時刻有多條指令在多個處理器上同時執行;並行才旨在同一時刻只能有一條指令執行,但多個進程指令被快速輪換執行,使得在宏觀上具有多個進程同時執行的效果。
大部分作業系統都支援多進程並行執行,現代的作業系統幾乎都支援同時執行多個任務。例如,程式設計師一邊開著開發工具在寫程式,一邊開著參考手冊備查,同時還使用電腦播放音樂……除此之外,每台電腦執行時還有大量底層的支撐性程式在執行……這些進程看上去像是在同時工作。
但事實的真相是,對於一個 CPU 而言,在某個時間點它只能執行一個程式。也就是說,只能執行一個進程,CPU 不斷地在這些進程之間輪換執行。那麼,為什麼使用者感覺不到任何中斷呢?
這是因為相對人的感覺來說,CPU 的執行速度太快了(如果啟動的程式足夠多,則使用者依然可以感覺到程式的執行速度下降了)。所以,雖然 CPU 在多個進程之間輪換執行,但使用者感覺到好像有多個進程在同時執行。
現代的作業系統都支援多進程的並行執行,但在具體的實現細節上可能因為硬體和作業系統的不同而採用不同的策略。比較常用的策略有:
-
共用式的多工操作策略,例如 Windows 3.1 和 Mac OS 9 作業系統採用這種策略;
-
搶占式的多工操作策略,其效率更高,目前作業系統大多採用這種策略,例如 Windows NT、Windows 2000 以及 UNIX/Linux 等作業系統。
多執行緒則擴充套件了多進程的概念,使得同一個進程可以同時併行處理多個任務。
執行緒(Thread)也被稱作
輕量級進程(Lightweight Process),執行緒是進程的執行單元。就像進程在作業系統中的地位一樣,執行緒在程式中是獨立的、並行的執行流。
當進程被初始化後,主執行緒就被建立了。對於絕大多數的應用程式來說,通常僅要求有一個主執行緒,但也可以在進程內建立多個順序執行流,這些順序執行流就是執行緒,每一個執行緒都是獨立的。
執行緒是進程的組成部分,一個進程可以擁有多個執行緒,一個執行緒必須有一個父進程。執行緒可以擁有自己的堆疊、自己的程式計數器和自己的區域性變數,但不擁有系統資源,它與父進程的其他執行緒共用該進程所擁有的全部資源。因為多個執行緒共用父進程裡的全部資源,因此程式設計更加方便;但必須更加小心,因為需要確保執行緒不會妨礙同一進程中的其他執行緒。
執行緒可以完成一定的任務,可以與其他執行緒共用父進程中的共用變數及部分環境,相互之間協同未完成進程所要完成的任務。
執行緒是獨立執行的,它並不知道進程中是否還有其他執行緒存在。執行緒的執行是搶占式的,也就是說,當前執行的執行緒在任何時候都可能被掛起,以便另外一個執行緒可以執行。
一個執行緒可以建立和復原另一個執行緒,同一個進程中的多個執行緒之間可以並行執行。
從邏輯的角度來看,多執行緒存在於一個應用程式中,讓一個應用程式可以有多個執行部分同時執行,但作業系統無須將多個執行緒看作多個獨立的應用,對多執行緒實現排程和管理,以及資源分配。執行緒的排程和管理由進程本身負責完成。
簡而言之,一個程式執行後至少有一個進程,在一個進程中可以包含多個執行緒,但至少要包含一個主執行緒。
歸納起來可以這樣說,作業系統可以同時執行多個任務,每一個任務就是一個進程,進程可以同時執行多個任務,每一個任務就是一個執行緒。
多執行緒的好處
執行緒在程式中是獨立的、並行的執行流。與分隔的進程相比,進程中執行緒之間的隔離程度要小,它們共用記憶體、檔案控制代碼和其他進程應有的狀態。
因為執行緒的劃分尺度小於進程,使得多執行緒程式的並行性高。進程在執行過程中擁有獨立的記憶體單元,而多個執行緒共用記憶體,從而極大地提高了程式的執行效率。
執行緒比進程具有更高的效能,這是由於同一個進程中的執行緒都有共性多個執行緒共用同一個進程的虛擬空間。執行緒共用的環境包括進程程式碼段、進程的公有資料等,利用這些共用的資料,執行緒之間很容易實現通訊。
作業系統在建立進程時,必須為該進程分配獨立的記憶體空間,並分配大量的相關資源,但建立執行緒則簡單得多。因此,使用多執行緒來實現並行比使用多進程的效能要高得多。
總結起來,使用多執行緒程式設計具有如下幾個優點:
-
進程之間不能共用記憶體,但執行緒之間共用記憶體非常容易。
-
作業系統在建立進程時,需要為該進程重新分配系統資源,但建立執行緒的代價則小得多。因此,使用多執行緒來實現多工並行執行比使用多進程的效率高。
-
Python 語言內建了多執行緒功能支援,而不是單純地作為底層作業系統的排程方式,從而簡化了 Python 的多執行緒程式設計。
在實際應用中,多執行緒是非常有用的。比如一個瀏覽器必須能同時下載多張圖片;一個 Web 伺服器必須能同時響應多個使用者請求;圖形化使用者介面(GUI)應用也需要啟動單獨的執行緒,從主機環境中收集使用者介面事件……總之,多執行緒在實際程式設計中的應用是非常廣泛的。