2009-11-12 79 views
17

我只關心如何sleep(time in ms)在C庫或基本上在操作系統級別實現...在OS級別如何實現睡眠?

我猜...

  1. 可能是基於你做的處理器速度雖然nop的循環(我不確定睡眠時間是否準確)...
  2. 處理器中的任何特殊寄存器,您在其中寫入某個值並且處理器僅停止指定的時間(這會非常低效,因爲處理器甚至不能運行其他程序)。

任何線索?可能C庫的源代碼可以解釋一下嗎?我並不太在乎「C」是如何實現它的......我只是想知道「睡眠()」函數是如何實現的。

回答

14

Sleep()在OS級別實現。當任務/線程/進程正在休眠時,處理器不會旋轉。這個特定的線程被放到待處理的隊列中(線程還沒有準備好運行),直到時間到了,線程將被放置在準備運行的隊列中。

與此同時,準備運行的其他線程將運行。

只有直到發生硬件中斷時沒有線程準備運行將操作系統進入空閒線程,這在一般發出關機指令(或進入低功耗狀態反正)處理器。

僅適用於非常簡單的系統(如最簡單的嵌入式系統),實際上可能只是實現爲一個繁忙的等待循環。

任何操作系統教科書(如"Modern Operating Systems" by Tanenbaum)都會對此進行詳細介紹 - 幾乎所有操作系統(即使是舊的,便宜的)。

+0

ahhh ..所以它不保證在超時後喚醒..它的調度器或基本上在系統中的其他任務......? – FatDaemon 2009-11-12 00:43:13

+3

超時過期後,任務將再次運行取決於調度程序。系統可以保證它會在超時過期後立即運行,但是我認爲大多數情況下只會將它放在準備運行的隊列中的適當位置(如果線程優先級大於任何其他),它會在下一次計劃時運行。 – 2009-11-12 00:46:07

+0

許多嵌入式處理器都有專用的睡眠指令 – mocj 2009-11-12 02:20:27

2

您的問題的答案完全取決於操作系統和實施。

一個簡單的方法來想一想:當你調用sleep(),操作系統計算喚醒時間,然後堅持你的優先級隊列過程中的某個地方。然後,它不會安排您的進程獲取任何執行時間,直到足夠的時間才能從隊列中彈出來的真實

1

你不做任何while循環,否則系統將無法做任何事 - 而不是鼠標,鍵盤,網絡響應等

通常是大多數操作系統做的是你加延遲到當前時間戳以獲取請求延遲的任務時的時間戳(假設此時沒有運行更高優先級的任務)並將[wakeupTimestamp,任務指針]添加到按升序排序的列表按時間戳。之後,操作系統執行上下文切換並運行下一個可用任務。系統會定期將睏倦列表上的最早時間戳與當前時間戳進行比較,如果截止日期已過,則會將睡眠任務移至「就緒」任務隊列中。

+0

你怎麼在第二部分中說出一些聰明的東西,而在第一部分中又如此愚蠢?一個while循環是可搶佔的,不會中斷任何鼠標事件。 – 2013-03-26 02:54:04

2

在一個典型的操作系統,睡眠調用到內核,它設置進程等到指定的時間已經過去,然後去,發現一些其他進程運行。如果沒有更好的做法,它將運行'閒置過程'。一旦時間流逝,調度程序將會注意到睡眠過程很順利,並且會再次調度。

+0

絕對需要注意的是,空閒進程是運行HLT指令的進程。在現代CPU中,它變得非常複雜,並且取決於睡眠時間段,它會下降到CN模式。 (C0清醒,C1短暫睡眠,... C7長時間睡眠) – 2013-03-26 02:51:58

1

睡眠會阻止您傳遞時間值的任務/線程。您的任務在那段時間內無法運行,或者直到發生其他有趣的事情(如信號),無論哪個更早。

睡眠呼叫select()並不常見,並且不傳遞描述符以等待並且超時值等於您的睡眠週期。

系統可以通過設置一個計時器在時間過去後到期,然後等待該計時器到期時將用信號發送的信號來實現此目的。因此它在信號量上被阻塞。