操作系統:線程總結


 

日期:2019/5/3

關鍵詞:操作系統;線程。

一、線程與進程

進程的特點:

  • 資源所有權:進程對資源(內存、I/O通道、I/O設備、文件等)具有控制權。
  • 調度/執行:進程是OS調度和分派的實體。

1.1 多線程模型

關鍵點:

  • TCB控制塊:寄存器的值、程序計數器、棧指針、優先級等與線程相關的狀態信息。
  • 所有線程共享進程的狀態和資源。例如,全局變量,文件描述符表。當一個線程以讀權限打開文件,其他線程也能讀取(無需重復open)

線程的優點:

  • 創建或者終止線程時空效率高。(Unix中,創建線程比創建進程的時間快10倍)
  • 線程切換比進程切換所花時間少。
  • 通信效率高。進程需要內核介入才能通信。

二、線程模型分類

2大類:用戶級線程(User Level Thread)和內核級線程(Kernel Level Thread)。

2.1 ULT

ULT線程管理由應用程序完成,內核意識不到線程的存在。(通信、調度等通過線程庫實現)

ULT線程調度與進程調度的關系,也是ULT與KLT的本質區別。

初始狀態:

線程庫中:線程2運行

OS內核中:進程B運行

假設1:線程2進行了一個將會阻塞進程B的系統調用(例如IO操作)。那么:

內核把B阻塞,切換到另外一個進程。

但在線程庫的角度看來,線程2仍處於運行狀態。(但從CPU的角度看,不是真的運行)

假設2:時鍾中斷到來,B用完其時間片,內核進行進程切換,B從運行轉為就緒。但在線程庫的角度看來,線程2仍處於運行狀態。

假設3:線程2運行到需要線程1執行某些動作的一個點。(例如,1負責數據輸入,2負責計算和輸出這種情況)

線程2阻塞,線程庫調度線程1運行。

總結:

  • b-d的三種狀態其實都是a的過渡。
  • 在b和c中,內核把控制權切換到進程B,線程2就會回復執行。
  • 進程在執行線程庫代碼時可被中斷,在中斷時可能處於線程切換狀態。(進程被恢復時,才能完成線程切換)

ULT優點:

  • 線程庫在用戶空間當中,線程切換不需要陷入內核。(節省2次上下文切換)
  • 可以自定義線程調度算法。
  • ULT可在任意OS中使用,不需要修改內核。

ULT缺點:

  • 有一個ULT進行系統調用,那么所有線程都會阻塞。
  • 純ULT策略,多線程的程序不能使用CPU的多核技術。(因為內核調度的是進程,所以在純ULT策略下,多線程並不是真的在並行)

2.2 KLT

純KLT下,線程管理由內核完成,應用級沒有線程管理的代碼(只提供API)。

如上圖4.5(b),此時內核的調度單位是線程,一個線程阻塞,其他線程仍然在真的執行(前提CPU是多核)。

但線程調度需要陷入內核,時間花銷更大。

一組對比實驗:

  • Null Fork:創建、調度、執行和完成調用一個空過程的進程/線程的時間。(派生一個線程/進程的開銷)
  • Signal-Wait:進程/線程給正在等待的進程/線程發信號,然后在某個條件上等待需要的時間。(完成一次同步的開銷)

2.3 ULT+KLT組合方式

三、Linux的線程和進程管理

 

3.1 Linux進程

Linux中的進程/任務由一個task_struct表示,它包含以下信息:

  • 進程的狀態(執行、就緒、掛起、停止、僵死)
  • 調度信息:一個進程可能是普通或實時的,並具有優先級,實時進程在普通進程之前調度。
  • 標識符:PID,用戶標識符和組標識符。組標識符用於給一組進程指定資源訪問權。
  • 進程通信:支持Unix SVR4通信。
  • 鏈接:到達父子進程的鏈接。
  • 時間和計時器:包括進程創建時刻和進程消耗CPU的時間總量。一個進程還可以有若干個間隔計時器,通過系統調用來定義,計時器滿,OS會給該進程發送一個信號。計時器可以只使用一次或者多次。
  • 文件系統:包括被該進程打開的任何文件的指針和指向該進程當前目錄的指針。
  • 地址空間:定義分配給該進程的虛擬地址空間。
  • CPU專用上下文:寄存器、棧指針。

3.2 Linux線程

傳統Linux內核:

  • 單線程進程,不支持多線程
  • 多線程程序需要用戶線程庫實現(也就是純ULT策略),最著名的就是pthread庫了。(所以即使在多核CPU環境下,使用pthread庫寫的多線程排序時間效率上並不比單線程好,因為這種情況下CPU調度進程(在CPU看來這個進程只有一個線程),實際上就是多個線程輪流使用CPU的某個核)

現代Linux內核:

  • 不區分進程和線程
  • 提供內核級線程的實現
  • 將ULT映射到內核級進程
  • 組成一個用戶級進程的多個ULT則映射到共享同一個組ID的多個Linux內核進程上(這些進程可共享文件和內存等資源,使得同一個組的進程調度不需要上下文切換)。

fork底層是通過clone系統調用實現,將所有標志位清零。標志位如下:

當進行進程切換時,內核先檢查當前進程的頁目錄地址是否與被調度的進程相同。若相同,則他們共享一個地址空間,此時上下文切換僅僅是PC指針的跳轉。注意:clone可以使同一個進程組的克隆進程共享同一內存空間,但不能共享同一個用戶棧,每個clone進程都有獨立的棧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM