執行緒中,乙個對映表 對應 多個指令序列,會加快切換速度,切換指令需序列,只要改pc值就可以了
執行緒切換,是從一段程式,切換到 另一段程式
啟動多個執行序列(create),關鍵是 要交替執行,多個執行序列切換 需要 用yield 實現跳轉,主動釋放執行權
1.程式開始執行,執行函式a,a呼叫b,將 104 壓棧,跳到b執行
2.b呼叫了 yield,將 204 壓棧(此時棧中是 204,104),修改pc指標,跳到 yield 執行,yield 跳到 300,執行300 處的 c函式,
3.c呼叫了d,將304壓棧(此時棧是 304, 204, 104),跳到d執行
4.d呼叫了 yield2,將 404壓棧(此時棧是 404, 304, 204, 104),執行 yield2,跳到 204執行,204是 b的結束符 },} 會轉化為 ret,要彈棧,彈出 404,會跳轉到 404 執行。
預期 204 結束之後,應該回到 a執行,應該回到 104,上邊的例子回到了 404
如果2個執行緒 對應2個棧呢?
1.a執行,a呼叫b,將 104壓棧,跳到 b 執行
2.b呼叫了 yield,將 204 壓棧(棧1 中 204, 104),用tcb 儲存棧,esp儲存棧的指標
yield()
3.yield執行,跳到 300 執行,c 呼叫 d,將 304 壓入棧2 中,跳到d
4.d執行,將 404壓入棧2(棧2 中 404, 304),執行 d 中的yield
按照 預期,圖中的 (2)執行完,應該到(3),此時要 切換 執行序列 和對應的棧
此時的yield,要實現 cpu中的物理暫存器esp = tcb1 的 esp,pc = 204
yield()
此時yield中 ,是否需要 jmp 204:
- 如果有 jmp 204,當前棧1 是 204, 104,執行 jmp 204 不會執行 yiled的 },跳到 204, 是b的 } ,彈出的是204
- 如果沒有 jmp 204,當前棧1 是 204, 104,執行 yield的 } ,204出棧,204處是 b的 },104出棧,與我們預期相符
所以,yield中應該只切換棧,不要加 jmp
核心是要 建立 tcb,棧,指令的首位址,關聯 tcb與棧(tcb的esp儲存 棧的指標)
voidthreadcreate(a)
切換時,先找到 目標執行緒的 tcb,找到 目標tcb對應的esp,物理 esp = 目標tcb.esp,通過 yield的 } 彈棧
兩個執行緒:getdata,show
建立執行緒:建立對應的 tcb,esp,棧,關聯tcb和棧
切換執行緒:執行getdata,呼叫yield,先切換棧,再通過 yield的 } 彈棧
使用者程式 完全 執行在使用者態,切換也在使用者態進行,核心感知不到 這種切換。
yield的使用者程式,在使用者態切換
getdata()
show()
建立核心級執行緒時,由系統建立執行緒,threadcreate在核心中,tcb在核心中,如果getdata阻塞了,核心知道 show的存在,可以呼叫show 顯示資料
切換執行緒,使用者態是 yield,核心態是 schedule
基於ucontex實現使用者級執行緒
ucontext 是linux 系統自帶的使用者級執行緒上下文,標頭檔案 ucontext.h 我們可以用它來實現自定義的使用者級執行緒。l基本型別 1 ucontext t 型別typedef struct ucontext 使用者級執行緒上下文 ucontext t 2 stack t type...
核心級執行緒與使用者級執行緒
這兩天在寫這篇blog的時候,順帶複習作業系統的資料,遇到了乙個之前沒有弄明白的問題,就是關於核心級執行緒與使用者級執行緒。在查閱了一些資料之後,發表一下我個人簡介。執行緒已經在許多系統中實現,到那時各個作業系統實現方式不完全相同。kst 核心支援執行緒是在核心空間實現的 核心為每個執行緒在核心空間...
執行緒模型 使用者級執行緒與核心級執行緒介紹與對比
使用者級執行緒 一 概述 使用者級執行緒的實現就是把整個執行緒實現部分放在使用者空間中,核心對執行緒一無所知,核心看到的就是乙個單執行緒程序。對於執行緒的底層實現,現在很少有作業系統會使用單純的使用者級執行緒這中線程模型來實現。注 對於實現的是使用者級執行緒的作業系統而言,cpu 排程的基本單位看起...