進程(Process、行程)、線程(Thread、執行緒)、多線程(Multithreading、多執行緒)、Intel 超線程技術(Hyper-Threading、超執行緒技術) 簡介

昨天跟某個大陸網友在聊天,他傳了一張進程截圖過來,表示他在編譯他們公司的專案,原來是在進行 分布式編譯是四個進程,問他同時四個在編譯工作?,網友:四核心八線程,所以是八個。

其實對於 進程(Process) 的概念還算清楚(作業系統實現的概念,工作管理員打開裡面一個個就是了),可是對於 線程(Thread) 一直有點模糊,然後 CPU 的四核心八線程 又是啥意思呢?其實也有點「霧裡看花」

Thread 算是還蠻重要的概念,主要的應用地方還蠻多的 » 1. CPU(超線程技術) 2.作業系統(線程) 3.開發(多線程),由硬體至系統到開發都有 Thread 的概念,所以決定好好跟他認識一下。

下面基本上都是理論的東西,沒有實作,算是筆記一下自己的理解。

進程(Process)

進程在傳統上來說會跟「程式(Program)」意義共用

程式(Program),本身只是指令、資料及其組織形式的描述,意思就是實際上程式只是一個概念上的東西,如果有學過物件導向的話,程式(Program) 比較像是 Object 的概念。

而 進程(Process) 是 程式(Program) 實體化的概念,進程才是程式(那些指令和資料)的真正執行實體項。若干 進程 有可能與同一個程式相關聯,且每個行程皆可以同步(循序)或非同步(平行)的方式獨立執行。

面向行程設計的系統(如早期的UNIX,Linux 2.4及更早的版本)中,進程是程式的基本執行實體;在面向線程設計的系統(如當代多數作業系統、Linux 2.6及更新的版本)中,行程本身不是基本執行單位,而是 線程(Thread) 的容器。

所以可以知道,進程(Process)在作業系統中的定義由各自作業系統 設計、實現,UNIX 系統將 進程(Process) 作為最基本的執行單位(現代作業系統則是 Thread),而現代化的作業系統,則將進程設計為裝載 線程(Thread) 的一個設計。

所以在最底層的處理中,作業系統不是直接處理 進程(Process),而是 線程(Thread),當然 進程(Process)並非只是一個單純的容器,作業系統通常還會賦予 進程(Process) 一些實體的意義,eg. 父進程(Parent Process)、子進程..等等 (具體實現、設計不清楚,Ming 還沒學過 作業系統 理論,所以只能稍微介紹到這裡)

進程在作業系統中呈現的舉例:xxx.out、xxx.exe … 等等

0

進程包含 父進程、子進程 的概念

1

父進程、子進程不一定是由同一個廠商實作(例如下圖的 Lawlietfox、Microsoft PowerPoint 僅互為呼叫關係)由 父進程 呼叫皆可以算 子進程,父進程 結束工作後,作業系統會將子進程變為獨立進程(UNIX-base 則是由 init 收養)

2

進程內也可以包含一個以上的 線程(多線程)。

線程(Thread)

線程(Process) 是作業系統能夠進行運算排程的最小單位,被包含在 進程(Process) 中,在進代作業系統中,被設計為 進程(Process) 中的實際運作單位。

意思就是一個 進程(Process) 中可以包含一條或多條 線程(Thread)。

一個進程包含一個線程(單線程):

3

一個進程也可以包含多個線程(多線程(Multithreading)):

4

線程(Thread) 從開發的角度上來看,就是一條 程式碼執行的路徑。

例如,下面程式碼,進入 main() 之後,就會按照程式碼撰寫的路徑循序執行,進程(Process) 只擁有一條 線程(Thread)的狀況下,僅能一次完成一項工作。

example.cpp
1
2
3
4
5
6
7
8
9
10

int main()
{
cout « “Hello, world” « endl;
cout « “Hello, Tumblr” « endl;
message();
sendFile();
message();
return 0;
}

我們都知道程式呼叫 函數(function) 之後,程式的控制權會轉到 function 裡面去,那麼如果上面是一個 IM(即時通訊軟體),可能就會出現問題,當呼叫 message() 的時候,你不能做其它操作(例如:senfFile(送出檔案給對方)),你想送檔案給對方,呼叫 sendFile(),程式的控制權就會轉移到 sendFile() 中,也就是說這段時間 使用者無法再進行 訊息傳送、UI…等等(UI 畫面會整個卡死)。

當然這不是使用者所希望的,所以就有 多線程(Multithreading) 的概念,可以幫助同時執行多項操作:UI、Message、sendFile、addFriend。聰明的你一定想到,那如果用多個進程是否也可以(UI.exe、sendFile.exe、addFirend.exe)?。

答案是可以,前面忘記講一個很重要的概念,一個 進程(Process) 下面的一條或多條 線程(Thread),部分資源(eg. 虛擬位址空間,檔案描述符和訊號處理…等等)是共享的(呼叫棧(call stack)、暫存器環境(register context)、線程本地儲存(thread-local storage))、,也就是說 線程(Thread) 間的通信相對 進程(Process) 來說會比較容易。

有研究過 防毒軟體(Antivirus software) 的人一定知道,有些 防毒軟體 兩、三個進程,有的軟體可以到 七、八個進程,分成多個 獨立進程 雖然有缺點,但是也有一些優點,例如:便於開發、更新、升級、穩定性(例如以 瀏覽器(browser) 的分頁來說 Firefox 單獨只有 firefox.exe 這個進程(可能還有另外一個 plugin-container.exe),所有分頁是用多條線程完成,而 Chrome 則是每個分頁都相當於一個執行個體(多進程),所以 Firefox 崩潰通常都是整個 進程 崩潰(plugin-container.exe 可能還活著),而 Chrome 則透過多進程的方式避免一個分頁出問題,導致整個程序都出問題,當然相對 多線程 來說開發上會比較麻煩。

5

番外篇:Intel 超線程技術(Hyper-Threading、超執行緒技術)

常常聽到賣家在強調 四核心八線程(執行緒)、超線程技術(H-T),這是什麼意思呢?。

在 Intel 還沒有發展超線程技術前,一個 CPU核心 只能執行一條線程,四個CPU核心 只能執行四條線程,所以多核心可以一次執行四條線程的處理,而單核心一次只能執行一條線程(不具備多線程),,所以後來有 多核心CPU 的概念,為了就是能夠一次執行多條線程操作。

當然人類是不滿足的,為了能夠更加有效的利用資源,Intel 發展出 超線程技術(Hyper-Threading),可以讓一個 CPU(物理核心) 變成兩個邏輯核心,也就是說 單核心的CPU 也能具備多線程的能力。

當然,這種設計有利有弊,會造成耗電、發熱增高,所以 H-T 技術沉寂一段時間。

單核心單線程時代能夠有線程的概念是由於作業系統實現 時分復用 的設計。


大致上就是這樣子,因為 Ming 沒有學過 作業系統 理論,所以可能描述的 理論過程 與實際上有些出入,還請各位先進、前輩不吝指教。

還有一些 Mutual exclusion、Semaphore、時分復用 的概念沒寫到,有興趣可以自己找一下資料,描述了一些 作業系統<>線程(Thread) 間調度處理上的運作。

reference