說說Thread.Sleep(0)的那些奇怪的事


寫在前面

最近在弄一個傳輸組件,用到很多多線程的知識,其中有個問題,困擾我很久,不知道是什么原因,腦子一熱,在傳輸過程中,添加了一句代碼Thread.Sleep(0)。那個問題竟然解決了,耗費我一上午的時間,一點一點的排查是不是代碼邏輯有問題。到最后一句話解決了,興奮歸興奮,但是為什么這句話就能解決我的問題呢?而且還是睡個0,是不是你也遇到過這種情況?不妨一起討論下這句神奇的代碼!

Thread.Sleep(0)妙解

這里收集了網上的一篇文章,解釋的非常有趣,轉載在博客中,也推薦給大家一起看看。

[轉載]Thread.Sleep(0)妙用

摘錄文章的幾段話,你也可以有個大概的概念。

操作系統中,CPU競爭有很多種策略。Unix系統使用的是時間片算法,而Windows則屬於搶占式的。

  • 在時間片算法中,所有的進程排成一個隊列。操作系統按照他們的順序,給每個進程分配一段時間,即該進程允許運行的時間。如果在 時間片結束時進程還在運行,則CPU將被剝奪並分配給另一個進程。如果進程在時間片結束前阻塞或結束,則CPU當即進行切換。調度程序所要做的就是維護一張就緒進程列表,當進程用完它的時間片后,它被移到隊列的末尾。
  • 所謂搶占式操作系統,就是說如果一個進程得到了 CPU 時間,除非它自己放棄使用 CPU ,否則將完全霸占 CPU 。因此可以看出,在搶占式操作系統中,操作系統假設所有的進程都是“人品很好”的,會主動退出 CPU 。在搶占式操作系統中,假設有若干進程,操作系統會根據他們的優先級、飢餓時間(已經多長時間沒有使用過 CPU 了),給他們算出一 個總的優先級來。操作系統就會把 CPU 交給總優先級最高的這個進程。當進程執行完畢或者自己主動掛起后,操作系統就會重新計算一 次所有進程的總優先級,然后再挑一個優先級最高的把 CPU 控制權交給他。

一個例子

例子說明:在控制台中創建兩個線程,在線程中分別輸出0-100的數字,代碼如下:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Thread thchild = new Thread(new ParameterizedThreadStart(Run));
 6             thchild.Start("thread  1 開始");
 7             Thread thchild2 = new Thread(new ParameterizedThreadStart(Run));
 8             thchild2.Start("thread 2 開始");
 9             Console.Read();
10         }
11         static void Run(object obj)
12         {
13 
14             for (int i = 0; i < 100; i++)
15             {
16                 Console.WriteLine(obj.ToString() + "\t" + i.ToString());
17                 //Thread.Sleep(0);
18             }
19         }
20     }

測試結果

加上Thead.Sleep(0)測試結果

通過上面兩張圖的簡單對比,有這樣一種現象

在沒有Thread.Sleep(0)的時候,Thread1和Thread2交換的頻率比較低,在使用了Thread.Sleep(0)的時候,Thread1和Thread2交換頻率明顯增高。

總結

關於Thread.Sleep(0)的詳細內容可參考上面轉載的那篇文章,覺得介紹的更詳細,也比較有趣。當然給的例子,也是一種猜測性質的,系統中跑了那么多的線程,是不是對這個測試結果有干擾,也未可知。也不知道該怎么測試更合適。如果您也遇到過這種情況,不妨留言,討論一下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM