Использование сна и выберите с помощью сигналов - PullRequest
3 голосов
/ 04 марта 2011

Я хочу использовать функцию select() для ожидания в течение 1 секунды, так как моя программа использует сигналы для управления вещами, поэтому sleep() вернется преждевременно. Странно то, что при использовании select() он также возвращается преждевременно.

Я звоню, выбери вот так

struct timeval timeout;    
timeout.tv_sec = 10;  
timeout.tv_usec = 1000000; 
select (0 ,NULL, NULL, NULL, &timeout);

но всякий раз, когда приходит сигнал, он возвращается (я использую нано секундный таймер для сигнала)

Кто-нибудь знает почему?

Ответы [ 2 ]

5 голосов
/ 05 марта 2011

Попробуйте что-то вроде этого:

struct timespec timeout;
timeout.tv_sec = 10;
timeout.tv_nsec = 0;
while (nanosleep(&timeout, &timeout) && errno == EINTR);

Указатель «оставшегося времени» на nanosleep позаботится о том, чтобы позволить вам перезапустить сон с необходимым количеством оставшегося времени, если оно будет прервано.

4 голосов
/ 04 марта 2011

man 7 signal говорит:

Прерывание системных вызовов и библиотечных функций обработчиками сигналов

Если обработчик сигнала вызывается во время блокировки системного вызова или вызова функции библиотеки,затем либо:

   * the call is automatically restarted after the signal handler
     returns; or

   * the call fails with the error EINTR.

Какая из этих двух моделей поведения зависит от интерфейса и от того, был ли установлен обработчик сигнала с использованием флага SA_RESTART (см. sigaction (2)).Детали различаются в разных системах UNIX;ниже приведены подробности для Linux.

Если обработчик сигнала прервет заблокированный вызов одного из следующих интерфейсов, то вызов будет автоматически перезапущен после того, как обработчик сигнала вернется, если был использован флаг SA_RESTART;в противном случае вызов завершится с ошибкой EINTR

Как правило, проверка правильности возвращаемого значения -1 и errno == EINTR, а затем повторный вызов функции - правильный способ исправить это.

...