这次将描述如何不适用内核模式的方式来使线程等待。SpinWait,它是一个混合同步构造,被设计为使用用户模式等待一段时间,然后切换到内核模式以节省CPU时间。

代码Demo:

using System;
using System.Threading;

在Main方法下面加入以下代码片段:

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");
}

在Main方法中加入以下代码片段

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 hybrid SpinWait construct waiting");
t2.Start();
Thread.Sleep(5);
_isCompleted = true;

工作原理:

当主程序启动时,定义了一个线程,将执行一个无止境的循环,知道20毫秒后主线程设置 _isCompleted变量为true。我们可以试验运行该周期为20~30秒,通过Windows任务管理器测量CPU的负载情况。取决于CPU内核数量,任务管理器将显示一个显著的处理时间。

我们使用volatile关键字来声明_isCompleted静态字段。Volatile关键字指出一个字段可能会被同事执行的多个线程修改。声明为volatile的字段不会被编译器和处理器优化为只能被单个线程访问。这确保了该字段总是最新的值。

然后我们使用了SpinWait版本,用于在每个迭代打印一个特殊标志位来显示线程是否切换为阻塞状态。运行该线程5毫秒来查看结果。刚开始,SpinWait尝试使用用户模式,在9个迭代后,开始切换线程为阻塞状态。如果尝试测量该版本的CPU负载,在Window任务管理器将不会看到任何CPU的使用。

线程同步-SpinWait的更多相关文章

  1. C#多线程之线程同步篇3

    在上一篇C#多线程之线程同步篇2中,我们主要学习了AutoResetEvent构造.ManualResetEventSlim构造和CountdownEvent构造,在这一篇中,我们将学习Barrier ...

  2. C#多线程之线程同步篇1

    在多线程(线程同步)中,我们将学习多线程中操作共享资源的技术,学习到的知识点如下所示: 执行基本的原子操作 使用Mutex构造 使用SemaphoreSlim构造 使用AutoResetEvent构造 ...

  3. 【C#进阶系列】28 基元线程同步构造

    多个线程同时访问共享数据时,线程同步能防止数据损坏.之所以要强调同时,是因为线程同步问题实际上就是计时问题. 不需要线程同步是最理想的情况,因为线程同步一般很繁琐,涉及到线程同步锁的获取和释放,容易遗 ...

  4. C#中的线程(二) 线程同步基础

    1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...

  5. C#并行编程-线程同步原语

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  6. C#编程总结(三)线程同步

    C#编程总结(三)线程同步 在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应.对于服务器应用程序,多 ...

  7. [转]C#编程总结(三)线程同步

    本文转自:http://www.cnblogs.com/yank/p/3227324.html 在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时的任务可 ...

  8. .net线程同步

    大家都晓得.NET中线程同步有以下几种方式: 临界区(Critical Section).互斥量(Mutex).信号量(Semaphore).事件(Event) 1.临界区:通过对多线程的串行化来访问 ...

  9. C#当中的多线程_线程同步

    第2章 线程同步 原来以为线程同步就是lock,monitor等呢,看了第二章真是大开眼界啊! 第一章中我们遇到了一个叫做竞争条件的问题.引起的原因是没有进行正确的线程同步.当一个线程在执行操作时候, ...

随机推荐

  1. cmd命令行的ping用法

    1.打开cmd 2.ping 域名    (如:ping baidu.com) 3.输出结果 C:\WINDOWS\system32>ping baidu.com 正在 Ping baidu.c ...

  2. 【WCF】解析WCF服务的搭建

    WCF是.NET提供的一种服务,可以将自己写的程序(完成特定功能,比如从数据库中读取数据操作等)分装成服务以后,发布到服务器上.然后会生成一个网址,客户端在编程的时候,可以引用这个服务,使用这个服务中 ...

  3. 配置logback

    相关组件] Logback是由log4j创始人设计的又一个开源日志组件. logback当前分成三个模块:logback-core.logback- classic和logback-access. l ...

  4. .NET Core+NLog+存储配置 日志存入到数据库

    nlog-config.xml 配置文件: <?xml version="1.0" encoding="utf-8" ?> <nlog xml ...

  5. 使用DNSPod解析Freenom域名

    注册Freenom域名 Freenom官网:http://www.freenom.com Freenom提供的顶级域名包括:tk,ml,ga,cf,gq 申请流程: 注册用户后登陆,然后查询并选择一个 ...

  6. linux 编译运行c文件

    在ubuntu安装gcc 编辑 test.c /* Not stdio.h */ #include <unistd.h> void main() { char str[100]; /*Wr ...

  7. Android 8 蓝牙打开过程

    packages\apps\Settings\src\com\android\settings\bluetooth\BluetoothEnabler.java @Override public boo ...

  8. myeclipse及Eclipse中.classpath、.project、.settings、.mymetadata(myeclipse特有)介绍

    引言 今天在创建java项目的时候遇到了很多的错误,在解决的过程中遇到了一些根本不知道什么作用的文件,然后按照网上的一些做法可以将问题解决,但是这也说明我们在学习的时候很多基础和细节的地方是我们薄弱的 ...

  9. win2003 序列号 windows2003 sp2可用序列号大全(准版与企业版)

    通用性好的win2003序列号: (推荐先用这个里面的) FJ8DH-TQPYG-9KFHQ-88CB2-Y7V3Y GRD4P-FTQQF-JCDM8-4P6JK-PFG7M JD7JX-KCDTH ...

  10. 聊聊IOCP,聊聊异步编程

    *:first-child { margin-top: 0 !important; } .markdown-body>*:last-child { margin-bottom: 0 !impor ...