併發系列之 sleep 0

2021-10-25 18:13:04 字數 2006 閱讀 5095

作業系統前置知識

在講兩者的區別前,先回顧一下作業系統的知識。

作業系統中,cpu競爭有很多種策略:

在時間片演算法中,所有的程序排成乙個佇列。作業系統按照他們的順序,給每個程序分配一段時間,即該程序允許執行的時間。如果在時間片結束時程序還在執行,則cpu將被剝奪並分配給另乙個程序。如果程序在時間片結束前阻塞或結束,則cpu當即進行切換。排程程式所要做的就是維護一張就緒程序列表,當程序用完它的時間片後,它被移到佇列的末尾。

所謂搶占式作業系統,就是說如果乙個程序得到了 cpu 時間,除非它自己放棄使用 cpu ,否則將完全霸佔 cpu 。

在搶占式作業系統中,假設有若干程序,作業系統會根據它們的優先順序飢餓時間等算出一 個總的優先順序來。作業系統就會把 cpu 交給總優先順序最高的這個程序。當程序執行完畢或者自己主動掛起後,作業系統就會重新計算一 次所有程序的總優先順序,然後再挑乙個優先順序最高的把 cpu 控制權交給他。

如果是unix作業系統,每個執行緒被分配固定的時間片。

如果是windows 作業系統,由於是根據優先順序來決定執行哪個執行緒,因此可能會出現這種情況,乙個優先順序高的執行緒正在執行,在某一時刻,該執行緒根據自己的「意願」選擇掛起,此時會重新計算優先順序,而剛剛選擇掛起的那個執行緒由於之前優先順序太高,且剛才執行的時間很短,導致就算該執行緒主動掛起,再次參與cpu競爭的時候其優先順序仍是最高的,那麼該執行緒仍然會被入選,但是其優先順序也可能不是最高的。

thread.sleep(0)

那麼,thread.sleep函式是幹嗎的呢?

比如當乙個執行緒執行thread.sleep(10000)時,該執行緒選擇掛起10秒,那麼作業系統在隨後的1秒裡重新計算所有執行緒總優先順序的時候,就會忽略該執行緒。即告訴作業系統「在未來的多少毫秒內我不參與cpu競爭」

那麼現在有兩個問題

假設現在的時間是12:00:00.000,如果呼叫thread.sleep(10000),即讓該執行緒掛起10秒,那麼在12:00:10.000 的時候,這個執行緒會不會被喚醒?

答案:不一定

因為你只是告訴作業系統:在未來的10秒內我不參與cpu競爭。那麼10秒過去之後,這時候也許另外乙個執行緒正在使用cpu,那麼這時候作業系統是不會重新分配cpu的,直到那個執行緒掛起或結束;況且,即使這個時候恰巧輪到作業系統進行cpu 分配,那麼當前執行緒也不一定就是總優先順序最高的那個,cpu還是可能被其他執行緒搶占。

與此相似的,thread有個resume函式,是用來喚醒掛起的執行緒的。跟上面所說的一樣,這個函式只是「告訴作業系統我從現在起開始參與cpu競爭了」,這個函式的呼叫並不能馬上使得這個執行緒獲得cpu控制權。

thread.sleep(0)呼叫與否的區別?

答案:有,而且區別很明顯。

thread.sleep(0)的作用,就是「觸發作業系統立刻重新進行一次cpu競爭」。競爭的結果也許是當前執行緒仍然獲得cpu控制權,也許會換成別的執行緒獲得cpu控制權。這也是我們在大迴圈裡面經常會寫一句thread.sleep(0),因為這樣就給了其他執行緒比如paint執行緒獲得cpu控制權的權力,這樣介面就不會假死在那裡。

此外,雖然上面提到說「除非它自己放棄使用 cpu ,否則將完全霸佔 cpu」,但這個行為仍然是受到制約的——作業系統會監控你霸佔cpu的情況,如果發現某個執行緒長時間霸佔cpu,會強制使這個執行緒掛起,因此在實際上不會出現「乙個執行緒一直霸佔著 cpu 不放」的情況。至於我們的大迴圈造成程式假死,並不是因為這個執行緒一直在霸佔著cpu。實際上在這段時間作業系統已經進行過多次cpu競爭了,只不過其他執行緒在獲得cpu控制權之後很短時間內馬上就退出了,於是就又輪到了這個執行緒繼續執行迴圈,於是就又用了很久才被作業系統強制掛起。因此反應到介面上,看起來就好像這個執行緒一直在霸佔著cpu一樣。

Sleep 0 及其使用場景

sleep n 的作用是讓當前執行緒睡眠n毫秒,以便執行其他執行緒,如果沒有其他執行緒,那睡眠n毫秒後,繼續執行。而如果n 0,sleep 0 是指cpu交出當前執行緒的執行權,讓cpu去執行其他執行緒。也就是放棄當前執行緒的時間片,轉而執行其他執行緒。那麼,sleep 0 應該在那種情況下使用?一...

Sleep 0 及其使用場景

sleep n 的作用是讓當前執行緒睡眠n毫秒,以便執行其他執行緒,如果沒有其他執行緒,那睡眠n毫秒後,繼續執行。而如果n 0,sleep 0 是指cpu交出當前執行緒的執行權,讓cpu去執行其他執行緒。也就是放棄當前執行緒的時間片,轉而執行其他執行緒。那麼,sleep 0 應該在那種情況下使用?一...

Sleep 0 及其使用場景

sleep n 的作用是讓當前執行緒睡眠n毫秒,以便執行其他執行緒,如果沒有其他執行緒,那睡眠n毫秒後,繼續執行。而如果n 0,sleep 0 是指cpu交出當前執行緒的執行權,讓cpu去執行其他執行緒。也就是放棄當前執行緒的時間片,轉而執行其他執行緒。那麼,sleep 0 應該在那種情況下使用?一...