用戶級線程和內核級線程(哈工大李志軍)

注:本文圖片引用自慕課的PPT
b站:https://www.bilibili.com/video/BV1d4411v7u7

用戶級線程

一個瀏覽器的模型:

在這裏插入圖片描述

兩個執行序列與一個棧的弊端:

在這裏插入圖片描述
Yield()是一個切換函數,在線程切換中,我們需要像Yield()這樣的函數允許B->C->D並直接返回 ->B,否則只能逐層調用返回,這不是線程切換想要的結果。

這種情況如果我們希望用Yield()D返回到B,即直接跳轉到204,但當函數返回時(ret指令),我們發現此時棧已經亂了,ret將會導致意外,會使程序跳轉到404.
在這裏插入圖片描述

從一個棧到兩個棧

在這裏插入圖片描述
如果使用兩個棧,那麼我們自然需要在Yield()中切換棧,把棧頂指針存入到該線程的TCB(線程控制塊)中。

當程序在D中,調用Yield()當前棧2頂部壓入404,調用Yield()時,交換棧,此時Yield()函數返回時彈出的棧是棧1,而此時棧1頂部爲204正好與我們跳轉到204的目的相同,因此Yield()不需要jmp 204

兩個線程:兩個TCB+兩個棧+切換的PC在棧中

在這裏插入圖片描述

用戶級線程的弊端

在這裏插入圖片描述

當用戶級線程調用內核時,進入內核態之後,若內核進程需要等待網卡IO,需要較長時間而導致進程阻塞,用戶態的多線程將沒有任何作用。

核心級線程

在這裏插入圖片描述
在這裏插入圖片描述
用戶線程是Yield(),內核線程切換Schedule()Schedule()調度是由系統決定,具有強制性,Yield()用戶可主動釋放。
如果實現了核心級線程,則有效解決了僅用戶級線程的缺陷。

切換進程與切換線程:

  • 進程需要分配資源,所以只有內核級的進程。
  • 切換進程:切換指令流 + 切換資源
  • 切換內核級線程即爲切換指令流,是切換進程中的一部分。

在這裏插入圖片描述
多處理器與多核的區別,多處理器每個運算器都有自己的緩存和內存映射,多核心處理器共用一個。
多核處理器要想有作用,必須支持核心級線程。
在多核處理器中, 因爲多個線程共用一個資源,多核被分配到多個線程,而只需一套MMU(內存管理單元)。

從一個棧到一套棧

每個用戶級線程即需要一個棧,而實現用戶級線程需要一套棧即兩個棧:用戶棧 + 內核棧
在這裏插入圖片描述

用戶棧到內核棧的關聯:

在這裏插入圖片描述
SS:SP爲用戶棧指針,CS:PC(IP)記錄用戶程序的位置。
在這裏插入圖片描述
在這裏插入圖片描述
esp 被賦值 爲TCB1中的值,執行sys_read()而阻塞,內核線程調度使用switch_to()並切換棧
cur是當前線程的TCB,next是下一個線程的TCB。
PC:CS 爲返回用戶態的地址,SS:SP指向用戶態棧。
要讓以上PC,CS,SS,SP都彈出棧,那麼? ? ? ? 的指令應爲iret (中斷返回)
在這裏插入圖片描述

小結:內核線程switch_to的五段論

在這裏插入圖片描述

  1. 準備中斷:爲整個處理鏈條做準備,中斷進入內核態
  2. 中斷處理:當引發阻塞(IO 或時鐘中斷)時
  3. 引發切換,並找到下一個TCBnext =...
  4. 內核棧切換:交換指針完成棧交換後,執行 ret 指令。
  5. 中斷出口:交換後將彈出當前棧頂即上文圖中的 ? ? ? ?的命令,在上文已經解釋到, ? ? ? ?iret(中斷返回),使 CS,PC,SS,SP等彈出棧,恢復到用戶態。
  6. (附加)因爲進程切換,還要切換地址映射表,到內存管理部分時再研究。

ThreadCreate 實現模型

在這裏插入圖片描述

  1. 申請內存:get_free_page()作爲TCB
  2. 內核棧初始化
  3. 傳入用戶棧
  4. 並將兩個棧通過指針連接起來,將內核函數地址(圖中爲500)和 CS (0F)壓入棧,並壓入參數。
  5. 設置TCB指向內核棧
  6. TCB就緒,入隊。

用戶級線程和核心級線程的對比

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章