2016-03-08 5 views
1
#include <signal.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <stdio.h> 

static jmp_buf env_alrm; 

static void sig_alarm(int signo) 
{ 
     longjmp(env_alrm, 1); 
} 
int sleep2(unsigned int seconds) 
{ 
     if(signal(SIGALRM, sig_alarm)==SIG_ERR) 
       return seconds; 

     if(setjmp(env_alrm)==0) //when it is first called, return value is 0 
     { 
       alarm(seconds); 
       pause(); 
     } 

     return (alarm(0)) 
}  

В этом коде я думаю, что это делает бесконечный цикл. Мои thinkings следующие:longjmp, бесконечный цикл setjmp

Мы называем sleep2() функции в основной, как sleep2(3), то после вызова pause(), SIGALRM будет доставлен через 3 сек. Таким образом, будет вызываться обработчик сигналов sig_alarm().

И, позвонив по телефону longjmp(), он перейдет в setjmp() Функция во сне2. И, наконец, после тестирования возвращаемого значения setjmp() (которое должно быть 1 после вызова longjmp()) оно выполнит return alarm(0). Таким образом, он немедленно вызовет sig_alarm() (потому что SIGALRM доставлен снова), и этот цикл будет продолжен.

Что мне не хватает?

+0

Используйте 'siglongjmp' в обработчике сигналов. Но сначала прочитайте [signal (7)] (http://man7.org/linux/man-pages/man7/signal.7.html), чтобы понять, что не следует. –

+1

Результатом тревоги является количество оставшихся секунд. Если есть 0 секунд повторного соединения, просто верните 0 вместо сигнала тревоги (0). – cup

ответ

2

alarm(0) не передает никаких аварийных событий. Он отменяет ранее запланированный аварийный сигнал и возвращает количество секунд, оставшихся до этого отмененного сигнала тревоги (если есть).

Последняя строка вашего кода не вызывает бесконечный цикл, потому что он не выполняет sig_alarm. Он возвращает количество секунд, оставшихся до обычного истечения срока действия вашего sleep2. В вашем маленьком примере это будет равно нулю. Ваш код, вероятно, является частью более крупного программного обеспечения, где longjmp (и последняя строка вашего sleep2) может быть выполнена до истечения таймера. В этом случае sleep2 возвращает количество секунд, оставшихся до нормального срока годности.

Смежные вопросы