深刻分析Sleep(0)与Sleep(1)的区别
罗朝辉 (http://blog.csdn.net/kesalin)
CC许可,转载请注明出处
目的:操作系统
有时候咱们想让线程不被调度必定的时间,也就是说让线程睡眠一段时间。.net
API 接口:线程
在 Win32中能够调用 Sleep,SleepEx 和 SwitchToThread 三个API。blog
VOID WINAPI Sleep(DWORD dwMilliseconds);接口
DWORD WINAPI SleepEx(DWORD dwMilliseconds, BOOl bAlertable);队列
BOOl WINAPI SwitchToThread();it
在托管代码中,咱们能够调用静态方法 Thread.Sleep。table
分析:方法
Sleep 接口均带有表示睡眠时间长度的参数 timeout。调用以上提到的 Sleep 接口,会有条件地将调用线程从当前处理器上移除,而且有可能将它从线程调度器的可运行队列中移除。这个条件取决于调用 Sleep 时timeout 参数。im
当 timeout = 0, 即 Sleep(0),若是线程调度器的可运行队列中有大于或等于当前线程优先级的就绪线程存在,操做系统会将当前线程从处理器上移除,调度其余优先级高的就绪线程运行;若是可运行队列中的没有就绪线程或全部就绪线程的优先级均低于当前线程优先级,那么当前线程会继续执行,就像没有调用 Sleep(0)同样。
当 timeout > 0 时,如:Sleep(1),会引起线程上下文切换:调用线程会从线程调度器的可运行队列中被移除一段时间,这个时间段约等于 timeout 所指定的时间长度。为何说约等于呢?是由于睡眠时间单位为毫秒,这与系统的时间精度有关。一般状况下,系统的时间精度为 10 ms,那么指定任意少于 10 ms但大于 0 ms 的睡眠时间,均会向上求值为 10 ms。
而调用 SwitchToThread() 方法,若是当前有其余就绪线程在线程调度器的可运行队列中,始终会让出一个时间切片给这些就绪线程,而无论就绪线程的优先级的高低与否。
结论:
由上面的分析能够看出,若是咱们想让当前线程真正睡眠一会儿,最好是调用 Sleep(1) 或 SwitchToThread()。