簡體   English   中英

實現用戶級線程包

[英]Implementing a User-Level Threads Package

我已經在一個類中負責在C中創建一個用戶級線程庫。我想知道是否有人可以給我一個事項列表來閱讀以實現這一目標。 我對從哪里開始有一個好主意,但是用戶級線程上的任何資源以及可能有用的C語言的一些適用方面都非常有價值。

我不清楚我將如何實現這樣的調度程序。 假設我對C語言及其一些更有用的庫函數有很好的理解。

我完成了這項工作,沒有任何匯編程序。 線程切換機制是setjmp / longjmp 這涉及為每個線程的堆棧分配內存,然后非常小心地按摩jmp_buff的值,以便執行跳轉到下一個線程的堆棧。

另請參閱Russ Cox非常易讀的libtask

編輯以響應OP的評論:在決定何時切換線程時,有兩個主要方向:搶先和合作。 在搶先模型中,你會有一些像定時器信號那樣導致執行流程跳轉到中央調度程序線程,該線程選擇下一個運行的線程。 在協作模型中,線程彼此“產生”,或者顯式地( 例如 ,通過調用您將提供的yield()函數)或者隱式地( 例如 ,請求由另一個線程持有的鎖)。

查看libtask的API以獲取合作模型的示例,尤其是函數taskyield()的描述。 這是我提到的明確收益率。 還有非阻塞I / O函數,其中包含隱式yield - 當前“任務”被暫停,直到I / O完成,但其他任務有機會運行。

一個簡單的協同調度可以在C使用swapcontext來完成,看在swapcontext手冊頁的例子在這里 ,這是它的輸出:

$ ./a.out
main: swapcontext(&uctx_main, &uctx_func2)
func2: started
func2: swapcontext(&uctx_func2, &uctx_func1)
func1: started
func1: swapcontext(&uctx_func1, &uctx_func2)
func2: returning
func1: returning
main: exiting

所以你可以看到它是非常可行的。

注意:如果您在計時器信號處理程序中交換上下文,那么您自己就是一個先發制人的調度程序,但我不確定這樣做是否安全或可行。

編輯:我在sigaction的手冊頁中發現了這一點,這表明可以在信號處理程序中切換上下文:

如果在sa_flags中指定了SA_SIGINFO,則sa_sigaction(而不是sa_handler)指定signum的信號處理函數。 此函數接收信號編號作為其第一個參數,指向siginfo_t作為其第二個參數的指針,以及指向ucontext_t (cast to void *) 的指針作為其第三個參數。

您可以查看Apple的開源實現。 請注意,代碼的最大部分實際上是匯編代碼,因為它需要一些您無法在C中執行的特殊操作,例如檢索堆棧幀的返回地址或跳轉到任意地址。

用戶態線程(通常也稱為“光纖”)通常采用協作模型; 也就是說,線程執行直到他們確定他們有足夠的時間,然后屈服於另一個線程。 使用優先級隊列,您可以實現一個調度程序,該調度程序執行已運行最短時間的任務。 (調度程序會跟蹤正在運行的任務,並且當運行任務確定已經足夠時,運行任務會返回。調度程序會更新任務運行的時間,然后生成執行時間最短的任務。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM