Как избежать прерывания спящих звонков из-за сигнала в Linux? - PullRequest
9 голосов
/ 08 февраля 2010

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

Кто-нибудь знает, как избежать этого поведения?

Я пытался использовать обычный сигнал (SIGUSR1), но продолжаю работать так же.

Ответы [ 5 ]

14 голосов
/ 08 февраля 2010

На странице man nanosleep:

nanosleep задерживает выполнение программы как минимум на время, указанное в * req.Функция может вернуться раньше, если сигнал был доставлен процессу.В этом случае он возвращает -1, устанавливает errno в EINTR и записывает оставшееся время в структуру, на которую указывает rem, если только rem не равен NULL.Значение * rem можно затем использовать для повторного вызова nanosleep и завершения указанной паузы.

8 голосов
/ 08 февраля 2010

Вы можете маскировать почти все сигналы (кроме SIGKILL), используя sigprocmask() или signal() вызовов Первая вернет вам предыдущую маску, которую вы можете восстановить после sleep(). Некоторые примеры здесь . Если это не поможет, пожалуйста, будьте более многословны с тем, какой сигнал прерывает ваш сон. Я думаю, вы можете дополнительно проверить это состояние («сон прерван сигналом?») И снова заснуть.

5 голосов
/ 08 февраля 2010

Более новые ядра Linux поддерживают signalfd (2) . Вместе с sigprocmask (2) это очень хороший способ объединить обработку сигналов и событий ввода-вывода в одном вызове epoll_wait (2) .

2 голосов
/ 08 февраля 2010

Ну, сигнал в реальном времени должен прерывать сон. Вместо этого вы можете использовать сигнал не в реальном времени. Другой подход состоит в том, чтобы проверить, истекло ли ожидаемое время для сна, и если нет, в течение оставшегося интервала.

2 голосов
/ 08 февраля 2010

Если вы не хотите, чтобы вас прерывали, почему вы используете сигнал в реальном времени?

Где-то, либо в «Расширенном программировании Unix» Рокинда, либо в книге Стивена, был пример того, как это подделать. Вы записываете текущее время перед началом сна. После того, как сон заканчивается, вы проверяете, прошло ли необходимое количество времени, а если нет, вы начинаете новый сон. Поместите режим сна в цикл, который рассчитывает время перехода в режим сна и выдает это количество, а затем завершается по истечении требуемого времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...