- Multithreading with C# Cookbook(Second Edition)
- Eugene Agafonov
- 438字
- 2021-07-09 19:35:38
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:
- Start Visual Studio 2015. Create a new C# console application project.
- In the
Program.cs
file, add the followingusing
directives:using System; using System.Threading; using static System.Console; using static System.Threading.Thread;
- 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"); }
- 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;
- 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.
- Extending Jenkins
- JavaScript從入門到精通(微視頻精編版)
- CentOS 7 Linux Server Cookbook(Second Edition)
- 區塊鏈架構與實現:Cosmos詳解
- DevOps入門與實踐
- 深入理解Elasticsearch(原書第3版)
- Python Data Structures and Algorithms
- Python程序設計開發寶典
- Distributed Computing in Java 9
- UX Design for Mobile
- WebStorm Essentials
- ArcPy and ArcGIS(Second Edition)
- Implementing Domain:Specific Languages with Xtext and Xtend
- 信息學奧林匹克競賽初賽精講精練
- 亮劍C#項目開發案例導航