如果 CPU 实际当前正在执行您的应用程序的代码,您的应用程序将在那个时刻被中断。您的应用程序不断地通过任务调度程序获取执行时间,这决定了哪个应用程序获得 CPU 时间、在哪个内核上以及持续多长时间。一旦系统真的进入睡眠状态时,调度程序不再为您的应用程序提供任何时间,因此它会在此时停止执行,这几乎可以在任何地方发生。但是,内核必须处于干净状态。这意味着如果您刚刚对内核进行了调用(许多 libC 函数都这样做)并且此调用不在某个安全点(例如休眠、等待条件变为真等)或可能持有关键的内核锁(例如漏斗),内核可能会暂停睡眠,直到此调用返回用户空间或执行达到这样的安全点,然后才最终从任务调度程序中取消您的应用程序。
您可以打开内核端口并注册睡眠/唤醒事件。在这种情况下,当系统想要进入睡眠状态时,您的应用程序将收到一个事件。你有几种可能性。一是回复它,系统可能会进步。另一种是暂停睡眠;但是,Apple 表示某些事件最多可以暂停 30 秒,之后,无论您的应用程序是否喜欢,系统都会继续运行。最后,您可以取消它;尽管并非所有活动都可以取消。如果系统已经决定要进入休眠状态,您最多只能暂停 30 秒或立即允许,不能取消。但是,您也可以收听一个事件,系统询问应用程序是否可以现在进入睡眠状态,您可以回复“否”,从而取消睡眠。
“可以睡觉了吗”和“我打算睡觉”之间的区别是:如果应用了省电设置,即如果用户没有移动鼠标或输入任何内容,则发送第一个在那里配置的时间。在这种情况下,系统只会询问睡眠是否正常。像 Apple 的 DVD 播放器这样的应用程序会说“不”,因为很可能用户观看了 DVD,因此不与计算机交互,仍然没有理由去睡觉。OTOH,如果用户关闭他的 Mac Book,则不会询问应用程序,系统肯定会进入睡眠状态,只是通知应用程序,现在最多有 30 秒的时间对其做出反应。
Wake-up events can also be quite interesting to catch. E.g. if your system wakes up, open files might be inaccessible (an external drive has been unplugged) or network sockets won't work any longer (network has changed). So you may re-init certain app parts before using them and running into errors that are more or less expected.
Apple's page regarding catching these events.