Linux進程和線程

程序是一組指令及參數的集合,指令按照既定的邏輯控制計算機運行。進程則是運行着的程序,是操作系統執行的基本單位。線程則是爲了節省資源而可以在同一個進程中共享資源的一個執行單位。

 

1. 程序和進程

 C、C++、Java等語言編寫的源程序經相應的編譯器編譯成可執行文件後,提交給計算機處理器運行。應用程序的運行狀態稱爲進程。進程與應用程序的區別在於應用程序作爲一個靜態文件存儲在計算機系統的硬盤等存儲空間中,而進程則是處於動態條件下由操作系統維護的資源管理實體。可以從以下幾個方面進行區別:

  • 進程是動態的,而程序是靜態的。

  • 進程有一定的生命週期,而程序是指令的集合,本身無"運動"的含義。

  • 一個進程只能對應一個程序,一個程序可以對應多個進程。進程和程序的關係就像戲劇和劇本之間的關係。

 

2. 進程

進程是指程序執行時的一個實例,由代碼、數據、系統資源和環境組成。每個運行的程序就是一個進程。

  • 進程是操作系統進行資源分配的基本單位,擁有完整的進程空間。

  • 進程有進程控制塊PCB,PCB記錄了進程上下文信息,系統通過PCB對進程進行調度。

  • 進程=程序+數據+PCB

 

每個進程在內核中都有一個進程控制塊(PCB)來維護進程相關的信息,Linux內核的進程控制塊是task_struct結構體,task_struct是Linux內核的一種數據結構,每個進程都把它的信息放在 task_struct 這個數據結構裏,task_struct 包含了以下內容:  

1).標示符 : 描述本進程的唯一標示符,用來區別其他進程。

2).狀態 :任務狀態,退出代碼,退出信號等。

3).優先級 :相對於其他進程的優先級。

4).程序計數器:程序中即將被執行的下一條指令的地址。

5).內存指針:包括程序代碼和進程相關數據的指針,還有和其他進程共享的內存塊的指針

6).硬件上下文數據:進程執行時處理器的寄存器中的數據。

7).IO狀態信息:包括顯示的I/O請求,分配給進程的I/O設備和被進程使用的文件列表。

8).記賬信息:可能包括處理器時間總和,使用的時鐘數總和,時間限制,記賬號等。

9).文件:描述符等

每個進程都有自己獨立的 mm_struct 結構(虛擬地址空間),各個進程都在自己的地址空間中活動,互不干擾。 mm_struct是對進程的地址空間(虛擬內存)的描述,包括:代碼段(代碼和常量),數據段(全局變量和靜態變量),擴展段(堆),堆棧。

 

3. 線程

進程中的一個執行路徑就叫做線程。

  • 線程是進程的一部分,如果沒有進行顯示的線程分配,可以認爲進程是單線程的;如果進程中建立了線程,則可認爲系統是多線程的。

  • 程序執行的最小單位,系統分配處理器時間資源的基本單元,內核的調度對象是線程。

  • 線程自己只擁有少量系統資源:程序計數器、一組寄存器、棧。

 

Linux實現線程的機制非常獨特。從內核的角度說,他並沒有線程這個概念。Linux把所有的線程都當做進程來實現。內核並沒有準備特殊的調度算法或者是定義特別的數據結構來表徵線程。相反,線程僅僅被視爲一個與其他進程共享某些資源的進程。每個線程都擁有唯一隸屬於自己的 task_struct ,所以在內核中,它看起來像是一個普通的進程(只是它和其他一些進程共享某些資源,如地址空間),只是它並沒有自己獨立的內存地址空間。

在linux中,實際上線程和進程使用的是同一個結構體 task_struct,在 linux 眼裏,不會區分進程和線程,內核在進程任務調度時,僅僅是根據調度算法選擇一個 task_struct,至於這個task_struct,到底是進程、還是線程,內核並不關心。

當創建一個線程時,創建一個 task_struct結構體,但是這個 task_struct 共享進程的虛擬內存 (也就是 task_struct 結構中的 mm_sruct mm字段)。

 

什麼情況下使用線程:

1)需要頻繁創建銷燬的優先使用線程,因爲對進程來說創建和銷燬一個進程代價很大

2)線程的切換速度快,所以在需要大量計算,切換頻繁時用線程,耗時的操作使用線程可提高應用程序的響應

3)因爲對CPU系統的效率使用上線程更佔優,所以可能要發展到多機分佈的用進程,多核分佈用線程

4)並行操作時使用線程,如C/S架構的服務器端併發線程響應用戶的請求

5)需要更穩定安全時,適合選擇進程;需要速度時,選擇線程更好

 

4. 區別

  • 因爲進程擁有獨立的堆棧空間和數據段,所以每當啓動一個新的進程必須分配給它獨立的地址空間,建立衆多的數據表來維護它的代碼段、堆棧段和數據段,這對於多進程來說十分“奢侈”,系統開銷比較大,而線程不一樣,線程擁有獨立的堆棧空間,但是共享數據段,它們彼此之間使用相同的地址空間,共享大部分數據,比進程更節儉,開銷比較小,切換速度也比進程快,效率高,但是正由於進程之間獨立的特點,使得進程安全性比較高,也因爲進程有獨立的地址空間,一個進程崩潰後,在保護模式下不會對其它進程產生影響,而線程只是一個進程中的不同執行路徑。一個線程死掉就等於整個進程死掉。

  • 體現在通信機制上面,正因爲進程之間相互獨立,進程的通信機制相對很複雜,譬如管道,信號,消息隊列,共享內存,套接字等通信機制,而線程由於共享數據段所以通信機制很方便。

  • 體現在CPU系統上面,線程使得CPU系統更加有效,因爲操作系統會保證當線程數不大於CPU數目時,不同的線程運行於不同的CPU上。

  • 進程——資源分配的最小單位,線程——程序執行的最小單位。

  • 進程的創建和撤消的開銷要遠大於線程創建和撤消的開銷

  • 進程間切換時,當前進程的CPU環境要保存,新進程的CPU環境要設置,線程間切換時只須保存和設置少量寄存器,並不涉及存儲管理方面的操作,可見,進程切換的開銷遠大於線程切換的開銷。

 

5. 關係

  • 一個線程只能屬於一個進程,而一個進程可以有多個線程,但至少有一個線程。線程是操作系統可識別的最小執行和調度單位。

  • 資源分配給進程,同一進程的所有線程共享該進程的虛擬地址空間資源(通過共享進程的mm_sruct)。 同一進程中的多個線程共享代碼段(代碼和常量),數據段(全局變量和靜態變量),擴展段(堆)。但是每個線程擁有自己的棧段,用來存放所有局部變量和臨時變量。

  • 處理器分給線程,即真正在處理器上運行的是線程。

 

 

 

發佈了165 篇原創文章 · 獲贊 114 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章