1. 程式人生 > >C#多執行緒程式設計筆記(2.8)-使用SpinWait類

C#多執行緒程式設計筆記(2.8)-使用SpinWait類

近來在學習Eugene Agafonov編寫的《C#多執行緒程式設計實戰》(譯),做些筆記也順便分享一下^-^

using System;
using System.Threading;

namespace SpinWait_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            var t1 = new Thread(UserModeWait);
            var t2 = new Thread(HybridSpinWait);

            Console.WriteLine("Running user mode waiting");
            t1.Start();
            Thread.Sleep(20);
            _isCompleted = true;
            Thread.Sleep(TimeSpan.FromSeconds(1));
            _isCompleted = false;
            Console.WriteLine("Running bybrid SpinWait construct waiting");
            t2.Start();
            Thread.Sleep(5);
            _isCompleted = true;

            Console.ReadKey();
        }

        static volatile bool _isCompleted = false;

        static void UserModeWait()
        {
            while (!_isCompleted)
            {
                Console.Write(".");
            }
            Console.WriteLine();
            Console.WriteLine("Waiting is complete");
        }

        static void HybridSpinWait()
        {
            var w = new SpinWait();
            while (!_isCompleted)
            {
                w.SpinOnce();
                Console.WriteLine(w.NextSpinWillYield);
            }
            Console.WriteLine("Waiting is complete");
        }
    }
}

程式執行結果如下


當主程式啟動時,定義了一個執行緒,將執行一個無止境的迴圈,直到20毫秒後主執行緒設定_isCompleted變數為true。我們可以試驗執行該週期為20~30秒,通過Windows工作管理員測量CPU的負載情況。取決於CPU核心數量,工作管理員將顯示一個顯著的處理時間。

我們使用volatile關鍵字來宣告_isCompleted靜態欄位。Volatile關鍵字指出一個欄位可能會被同時執行的多個執行緒修改。宣告為volatile的欄位不會被編譯器和處理器優化為只能被單個執行緒訪問。這確保了該欄位總是最新的值。

然後我們使用了SpinWait版本,用於在每個迭代列印一個特殊標誌位來顯示執行緒是否切換為阻塞狀態。執行該執行緒5毫秒來檢視結果。剛開始,SpinWait嘗試使用使用者模式,在9個迭代後,開始切換執行緒為阻塞狀態。如果嘗試測量該版本的CPU負載,在Windows工作管理員將不會看到任何CPU的使用。