【转】深入分析Sleep(0)与Sleep(1)的区别

源地址

 

感觉很有用途,对后续的调用有帮助就转过来了,和大家分享一下!

目的:
有时候我们想让线程不被调度一定的时间,也就是说让线程睡眠一段时间。

 

API 接口:

在 Win32中可以调用 Sleep,SleepEx 和 SwitchToThread 三个API。

VOID WINAPI Sleep(DWORD dwMilliseconds);

DWORD WINAPI SleepEx(DWORD dwMilliseconds, BOOl bAlertable);

BOOl WINAPI SwitchToThread();

 

在托管代码中,我们可以调用静态方法 Thread.Sleep。


分析:

Sleep 接口均带有表示睡眠时间长度的参数 timeout。调用以上提到的 Sleep 接口,会有条件地将调用线程从当前处理器上移除,并且有可能将它从线程调度器的可运行队列中移除。这个条件取决于调用 Sleep 时timeout 参数。

 

当 timeout = 0, 即 Sleep(0),如果线程调度器的可运行队列中有大于或等于当前线程优先级的就绪线程存在,操作系统会将当前线程从处理器上移除,调度其他优先级高的就绪线程运行;如果可运行队列中的没有就绪线程或所有就绪线程的优先级均低于当前线程优先级,那么当前线程会继续执行,就像没有调用 Sleep(0)一样。

 

当 timeout > 0 时,如:Sleep(1),会引发线程上下文切换:调用线程会从线程调度器的可运行队列中被移除一段时间,这个时间段约等于 timeout 所指定的时间长度。为什么说约等于呢?是因为睡眠时间单位为毫秒,这与系统的时间精度有关。通常情况下,系统的时间精度为 10 ms,那么指定任意少于 10 ms但大于 0 ms 的睡眠时间,均会向上求值为 10 ms。

而调用 SwitchToThread() 方法,如果当前有其他就绪线程在线程调度器的可运行队列中,始终会让出一个时间切片给这些就绪线程,而不管就绪线程的优先级的高低与否。

结论:
由上面的分析可以看出,如果我们想让当前线程真正睡眠一下子,最好是调用 Sleep(1) 或 SwitchToThread()

posted @   pmars  阅读(5760)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示