Что происходит с моим приложением, когда мой Mac ложится спать?

Когда Mac OS X переходит в спящий режим, из-за закрытия ноутбука или выбора "Сон" из меню Apple, как он приостанавливает выполнение процесса?

Я полагаю, что не оконные процессы просто приостанавливаются в произвольной точке исполнения. Это также верно для приложений Cocoa, или ОС ждет, пока управление не вернется к диспетчеру цикла выполнения, и не отправится спать в "известном" месте? Использует ли какая-либо современная ОС это, или она обычно достаточно безопасна, чтобы просто приостанавливать приложение независимо от того, что он делает?

Мне любопытно, потому что разрешение сна в любой момент означает, что с точки зрения приложения системные часы могут внезапно перескочить на значительное количество. Это возможность, которую я обычно не рассматриваю при кодировании.

Ответы

Ответ 1

Ваше приложение прерывается именно там, где это тот момент, если на самом деле процессор фактически выполняет код вашего приложения. Ваше приложение постоянно получает время выполнения планировщиком задач, которое определяет, какое приложение получает процессорное время, на каком ядре и на какое время. Как только система действительно заснет, планировщик просто не дает времени вашему приложению больше, поэтому он прекратит выполнение, где бы он ни находился в тот момент, что может случиться почти везде. Однако ядро ​​должно находиться в чистом состоянии. Это означает, что если вы только что вызвали ядро ​​(многие функции libC), и этот вызов не находится в какой-то безопасной точке (например, спящий режим, ожидая, когда условие станет истинным и т.д.) Или, возможно, проведет критические блокировки ядра (например, воронки), ядро ​​может приостановить спящий режим до тех пор, пока этот вызов не вернется в пространство пользователя, или выполнение не достигнет такой безопасной точки, прежде чем оно окончательно отменяет ваше приложение из планировщика задач.

Вы можете открыть порт ядра и зарегистрироваться для событий сна/пробуждения. В этом случае ваше приложение получит событие, когда система хочет заснуть. У вас есть несколько возможностей. Один из них - ответить на него, что система может прогрессировать. Другой - приостановить сон; однако Apple заявляет, что определенные события могут быть приостановлены не более чем на 30 секунд, после чего система будет просто продолжать, нравится ли ваше приложение или нет. И, наконец, вы можете отменить его; хотя не все события могут быть отменены. Если система уже решила, что она перейдет в спящий режим, вы можете приостановить ее не более чем на 30 секунд или разрешить ее сразу, вы не сможете ее отменить. Тем не менее, вы также можете прослушивать событие, когда система запрашивает приложения, если сейчас нормально спать и вы можете ответить "нет", в результате чего сон будет отменен.

Разница между "Спокойно спать" и "Я планирую переспать": первый отправляется, если применяются параметры энергосбережения, то есть если пользователь не переместил мышь или набрал что-либо на время, настроенное там. В этом случае система просто спросит, если сон все в порядке. Приложение вроде Apple DVD Player скажет "нет", потому что, скорее всего, пользователь смотрит DVD и, таким образом, не взаимодействует с компьютером, все еще нет причин для сна. OTOH, если пользователь закрывает свою Книгу Mac, приложения не спрашивают, система наверняка заснет и просто сообщит приложениям, у которых есть до 30 секунд, чтобы реагировать на них.

Пробуждение событий также может быть довольно интересно поймать. Например. если ваша система просыпается, открытые файлы могут быть недоступны (внешний диск отключен) или сетевые сокеты больше не будут работать (сеть изменилась). Таким образом, вы можете перезапустить некоторые части приложения перед их использованием и столкнуться с ошибками, которые более или менее ожидаются.

страница Apple о том, как поймать эти события.

Ответ 2

Это зависит от вашего приложения.
Если вы взаимодействуете с внешними системами (думайте о сети или делаете что-то поверх usb/firewire и т.д.), Это может быть затронуто. Приложение, работающее на OSX, запускается в течение ограниченного времени (макс. 10 мс), после чего оно прерывается ядром, которое планирует запуск нового процесса из очереди процессов для запуска на CPU. Это прозрачно для приложения, которое "думает", что оно все время работает на процессоре. Таким образом, переход к сна ничем не отличается - кроме того, что время прыгает вперед.
Если вам нужно знать, что произошел переход в спящий режим, обратитесь к этой технической заметке, в которой подробно описано, как получать уведомления об изменении состояния: Регистрация и отмена регистрации для уведомлений о сон и бодрствованиях

Ответ 3

Я считаю, что он просто приостанавливает все приложения, где бы они ни находились.

Помните, что это происходит все время. Приложения постоянно приостанавливаются и возобновляются из-за переключения контекста. Так что, действительно, часы могут перепрыгивать между любыми двумя инструкциями в вашем приложении, хотя обычно это не замечательно/значимо.

Если ОС ждало, что приложение вернется в какой-то основной цикл, вы можете столкнуться с ситуациями, когда приложения приводят к зависанию сна. Если они выполняют много работы и не возвращаются к диспетчеру цикла, они не позволят машине переспать. Это было бы не очень хорошо.:)

Ответ 4

И если вы установите время, оно также будет переходить к работающим программам. Ничего особенного.