睡眠 (系统调用)
计算机程序(或进程、任务或线程等)进入不活跃状态并持续一段时间,称為“睡眠”。当引发程序睡眠的代码所设定的内部计时器归零,或是此程序收到唤醒信号或中断时,程序将恢复执行。
睡眠中的程序也有可能不经唤醒而直接被终止。
用法
睡眠指令通常需要输入一个参数,以说明程序睡眠至少多长时间后才恢复执行。这一时间参数的单位通常是秒,有些操作系统可以提供更高精度,例如以毫秒或微秒作为单位。
Windows
Windows 操作系统中,Sleep()
函数仅有一个参数,即以毫秒计的睡眠时间。[1]Sleep()
函数包含于 kernel32.dll 中,但是原生操作系统的批处理文件却并不支持这一指令。安装诸如Windows 2003 Resource Kit等运行环境后,用户便可使用这一指令。[2]
C语言样例
Windows 操作系统中:
Sleep(2*1000); // 睡眠2秒
类Unix操作系统中:
sleep(2); // 睡眠2秒
底层功能

图中没有进程处于不可中断睡眠。
睡眠使得线程或进程让出他们占用的剩余时间片,并在 “不在运行”状态等待一段时间。虽然这段程序在睡眠前被设定了最短睡眠时长,可这并不意味着这段时间结束后此程序能够立即恢复运作——这取决于 调度程序 的分配、等待唤醒的程序的优先级和其他一些因素。在 POSIX 系统中, nanosleep 及其他类似的系统指令会被中断信号中断,相应程序也会停止睡眠。而 sleep 库函数却不尽相同,在一些老一点的操作系统中,它是通过调用 alarm 系统指令实现的,因而必须通过送信号的方式才能运作。
在Windows中,由于除了终止运行信号外没有专门的信号可以用于打断,睡眠函数是不可中断的。不过,Windows提供了 SleepEX 函数来实现通过 APC 调用控制睡眠进程的唤醒。
严格说来,一个线程也可以由于其他线程终止运行或抛出异常被唤醒。
使用场景
一些系统程序在事件轮询过程中从不被终止,只是在每个周期开始前进入睡眠状态,等待着某些事件的发生唤醒它们。当收到事件之后,它们就被唤醒去处理这些事件,然后进入下一个周期的等待。
还有一些程序周期性的从睡眠中恢复运行并收集事件。当运行恢复,程序拉取事件列表和状态变更情况,然后针对睡眠时发生的事件做相应处理,完成后再次进入睡眠,等待下一个时隙。这类事件被称作心跳事件,或“持久连接[5]”信号,可由上述类型的周期性程序发送。
sleep()
函数还在程序执行节奏需要放缓的时候被调用。例如长时间高负荷运行程序时应有包含睡眠函数的代码来减轻硬件过热带来的麻烦[6],或是解决遗留代码中不为人知的奇妙程序错误[7]。相比于使用仿真器实现的周期平衡的程序,睡眠-运行周期发生的程序的缺点在于如果切换速度不够快,交互式程序就会有明显的延迟,如果太快,唤醒时间就太短以至于无法完成全部工作。[8]
另见
- 系统时钟
- 睡眠模式
参考文献
- MSDN Library Reference - Sleep()
- batch file sleep command
- UNIX Man Page - SLEEP(3) 的存檔,存档日期2011-07-20.
- nanosleep.3p - Linux manual page
- . learnku.com. [2019-06-25].
- mion. . mion.faireal.net. 2016-12-06 [2017-02-09].
- Tomcat那些事儿. . 十条 | 开发者公众号大全. [2019-06-25].
- Marletta, Angelo. . GitHub. 2015-03-12 [2017-02-09].
- . man7.org. 2016-12-12 [2017-02-09].
- . Novell. 2009-02-21 [2017-02-09].
- Fusco, John. . Pearson Education. 2007-03-06. ISBN 9780132703048.