C# Thread.Sleep(0)有什么用?
14 个回答
更新:win10 2004 版更新之后,出现很大的变化。详情看这个: Windows Timer Resolution: The Great Rule Change 更新:win10 2004 版更新之后,出现很大的变化。详情看这个:
现在我不知道怎么获得高分辨率了。
==========================================
回答这个要先从线程时间精度(时间片)开始说起。
很多参考书说,默认情况下,时间片为 15ms 左右,但是这是已经过时的知识。
在老的 Windows 操作系统里,应用程序模式时时间片 15ms 左右,准确一点是 15.625 左右。服务器模式是其双倍。
但是在微软推行.Net 普及 Task之后,规则已经改动,并且做了精细的调节。
现在Win10的时间精度为1ms(不用担心谷歌浏览器修改时间精度了),Win2013服务器的时间精度为7ms,使用 微软提供的测试工具 可以测出来。
谢谢下面评论提供的命令行:
powercfg /energy
我们可以通过它可以更直观的看出:
因为有这个请求在,所以无论如何最低的计时器分辨率都只能为1ms。
所以,现在Win10 默认状态下,Sleep(1) 占时不再是15ms,而是 1ms 左右:
下面现在正式回答,
Thread.Sleep(0)
,
Thread.Yield()
,
Thread.Sleep(1)
有什么不同:
首先,
Thread.Sleep
只是放弃时间片的剩余时间,让系统重新选择调度一个合适的线程(其优先级等于或者高于当前线程)。在没有其他活动线程的情况下,使用
Sleep(0)
还是选上原来线程,即连任,如果连任了,系统不会对其做上下文切换,所以有:
其次,
Thread.Yield()
是什么呢?跟
Thread.Sleep
有点像,但是它跟
Thread.Sleep(0)
有点区别:系统选择继任时可以选择优先级比原来低的线程。
最后,
Thread.Sleep(1)
是什么情况呢?前面说了,
Thread.Sleep
只是放弃时间片的剩余时间,让系统重新选择调度一个合适的线程。但是
Thread.Sleep(1)
却让当前线程沉睡了(即使只有
1ms
)。也就是说,主动放弃下次竞选,所以不可能连任,系统上下文必然发生切换(优先级低于原线程的家伙也有机会)。
以上。
有的答主的答案是错的:
错误答案1:
Sleep(0)
不能降低CPU的占有率,只是改变了跟其他线程的占有比例,
Sleep(0)
在没有其他活动线程的情况下会马上返回。
错误答案2:
这个知识点不知道从何而来,难道是更老的 Windows?
错误答案3:
如前所述,Sleep(0) 和 Yield 是有重大区别的。