官术网_书友最值得收藏!

Using the SpinWait construct

This recipe will describe how to wait on a thread without involving kernel-mode constructs. In addition, we introduce SpinWait, a hybrid synchronization construct designed to wait in the user mode for some time, and then switch to the kernel mode to save CPU time.

Getting ready

To step through this recipe, you will need Visual Studio 2015. There are no other prerequisites. The source code for this recipe can be found at BookSamples\Chapter2\Recipe9.

How to do it...

To understand how to wait on a thread without involving kernel-mode constructs, perform the following steps:

  1. Start Visual Studio 2015. Create a new C# console application project.
  2. In the Program.cs file, add the following using directives:
    using System;
    using System.Threading;
    using static System.Console;
    using static System.Threading.Thread;
  3. Below the Main method, add the following code:
    static volatile bool _isCompleted = false;
    
    static void UserModeWait()
    {
      while (!_isCompleted)
      {
        Write(".");
      }
      WriteLine();
      WriteLine("Waiting is complete");
    }
    
    static void HybridSpinWait()
    {
      var w = new SpinWait();
      while (!_isCompleted)
      {
        w.SpinOnce();
        WriteLine(w.NextSpinWillYield);
      }
      WriteLine("Waiting is complete");
    }
  4. Inside the Main method, add the following code:
    var t1 = new Thread(UserModeWait);
    var t2 = new Thread(HybridSpinWait);
    
    WriteLine("Running user mode waiting");
    t1.Start();
    Sleep(20);
    _isCompleted = true;
    Sleep(TimeSpan.FromSeconds(1));
    _isCompleted = false;
    WriteLine("Running hybrid SpinWait construct waiting");
    t2.Start();
    Sleep(5);
    _isCompleted = true;
  5. Run the program.

How it works...

When the main program starts, it defines a thread that will execute an endless loop for 20 milliseconds until the main thread sets the _isCompleted variable to true. We could experiment and run this cycle for 20-30 seconds instead, measuring the CPU load with the Windows task manager. It will show a significant amount of processor time, depending on how many cores the CPU has.

We use the volatile keyword to declare the _isCompleted static field. The volatile keyword indicates that a field might be modified by multiple threads being executed at the same time. Fields that are declared volatile are not subject to compiler and processor optimizations that assume access by a single thread. This ensures that the most up-to-date value is present in the field at all times.

Then, we use a SpinWait version, which on each iteration prints a special flag that shows us whether a thread is going to switch to a blocked state. We run this thread for 5 milliseconds to see that. In the beginning, SpinWait tries to stay in the user mode, and after about nine iterations, it begins to switch the thread to a blocked state. If we try to measure the CPU load with this version, we will not see any CPU usage in the Windows task manager.

主站蜘蛛池模板: 手机| 高雄市| 嘉兴市| 论坛| 林甸县| 威宁| 象州县| 蛟河市| 雅江县| 怀宁县| 陇川县| 繁峙县| 广饶县| 东城区| 汝城县| 南江县| 白城市| 克什克腾旗| 宿松县| 盐池县| 霍林郭勒市| 稻城县| 勐海县| 湾仔区| 澄江县| 华池县| 马边| 宁明县| 通山县| 宜阳县| 上栗县| 永泰县| 溧水县| 达拉特旗| 梨树县| 临西县| 什邡市| 贺州市| 河曲县| 平乡县| 杭锦后旗|