Подтвердить что ты не робот

Когда и как прерываются системные вызовы?

Это вопрос о последующих действиях для Является успешным методом send() "atomic" ?, поскольку я думаю, что это фактически касается системных вызовов вообще, а не просто отправляет розетки.

Какие системные вызовы могут быть прерваны, а когда они есть, где обрабатывается прерывание? Я узнал о SA_RESTART, но не понимаю, что происходит.

  • Если я делаю системный вызов без SA_RESTART, вызов может быть прерван любыми прерываниями (например, пользовательскими вводами), которые не относятся к моему приложению, но требуют от ОС прервать мой вызов и сделать что-то еще? Или это прерывается только сигналами, которые непосредственно касаются моего процесса (CTRL + C, сокет закрыт,...)?

  • При настройке SA_RESTART, какова семантика send() или любого другого "медленного" syscall? Будет ли он всегда блокироваться до тех пор, пока все мои данные не будут переданы или сокет не снизится, или он не сможет вернуться с номером, меньшим, чем параметр count()?

  • Где выполняется перезапуск? Означает ли ОС, что я хочу, чтобы вызов был перезапущен при любых прерываниях, или какой-то сигнал был отправлен в мой процесс, а затем обработан библиотечным кодом? Или я должен сделать это сам, например. завершите вызов в цикле while и повторите попытку как можно чаще?

4b9b3361

Ответ 1

Системные вызовы могут быть прерваны любым signal, включая такие сигналы, как SIGINT (сгенерированные CTRL-C), SIGHUP и т.д.

Когда SA_RESTART установлен, a send() вернется (с посланным счетчиком), если какие-либо данные были переданы до получения сигнала, он вернет ошибку EINTR, если установлен тайм-аут отправки (так как те не может быть перезапущен), в противном случае перезапуск send().

Перезапуск системного вызова реализован в коде обработки сигнала ядра. Системный вызов внутренне возвращает -ERESTARTSYS при обнаружении ожидающего сигнала (или ожидания, прерываемого сигналом), что приводит к тому, что код обработки сигнала восстанавливает указатель инструкции и соответствующие регистры до состояния перед вызовом, делая повторный вызов syscall.