2010-09-23 43 views
4

我應該實現C的用戶級線程庫要做到這一點,我需要實現yield()createThread()destroyThread()功能。我相信我已經掌握了一些基本權利:線程在用戶空間和產量

要跟蹤的線程,我將使用ThreadControlBlock元素(在操作系統類似PCBs)看起來像這樣的隊列:

struct ThreadControlBlock { 
    int ThreadId, 
    u_context *context }; 

我們可以使用setcontext()系列功能來「保存」和「加載」上下文。 程序初始化時,不使用元素初始化ThreadQueue。

現在我沒有得到的部分:當一個線程調用yield()時,我得到當前上下文並將它保存在一個ThreadControlBlock並放入隊列中。然後獲取隊列中的第一個元素並在其中加載上下文,然後繼續執行。

的問題是,如果我這樣做,說我是一個線程調用yield()和下一個線程就是我自己。如果我保存上下文並重新加載,重新進入後我不會和我在同一個地方(在致電yield()之前?)這會一直持續下去嗎?

+0

+1相關的示範性問題到家庭作業,這不僅僅是「請爲我做作業」。這個問題本身就是一個有趣的問題,它是任務上下文切換實際工作的核心。 – RBerteig 2010-09-23 20:23:17

回答

0

如果您切換到另一個任務,實際上也適用同樣的問題 - 因爲其他任務在同一點(即將切換到第二個任務的位置)保存了其上下文。使用setcontext()getcontext(),你需要使用一個靜態變量來跟蹤你是否正在轉換或交換出去:或者

static volatile int switched; 

switched = 0; 
getcontext(current->context); 
if (!switched) 
{ 
    switched = 1; 
    setcontext(next->context); 
} 

,你可以只使用swapcontext(current->context, next->context);

0

它在你的yield()實現完全合理的檢查,看看下一個線程是當前線程和治療這種情況下,作爲一個無操作。

+0

我們被告知不要那樣做... – Aillyn 2010-09-23 19:37:48

+0

@pessimopoppotamus:如果沒有其他線程,那麼你必須這樣做。來自任務調度程序的有趣示例:它們都不支持0個任務。這就是爲什麼Windows有「系統閒置任務」和* NIX有「init」的原因。所以調度程序總是有一些安排。作爲調用者的調用,yield()本質上是一種允許[合作多任務](http://en.wikipedia.org/wiki/Computer_multitasking#Cooperative_multitasking.2Ftime-sharing)的方法。如果沒有人與之「配合」,yield()不能做任何事情。 – Dummy00001 2010-09-23 22:37:25

1

當一個線程調用yield(),你必須拯救一個線程,是關於從yield()調用返回的狀態。不要在yield()之前立即保存上下文。

0

如果除了當前線程之外沒有其他線程可以運行,那麼除了從yield返回之外沒有其他線程可以運行。在這種情況下,我不會打擾調用swapcontext,只是檢測並返回。

我認爲你實際處理的是當沒有線程(包括當前的線程)調用yield時要怎麼做。處理這個問題的簡單方法是擁有一個空閒線程,該線程僅在運行隊列(就緒線程)爲空時運行。這個線程可能只是:

{ 
     while (1) { 
      yield(); 
      pause(); 
     } 
    } 

這可以讓你的程序進入睡眠(通過暫停),直到信號發生。希望信號是一些事件,使其他線程中的一個準備運行,所以下一次調用yield將運行另一個線程,而不是再次運行空閒線程。

相關問題