#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))
}
在这段代码中,我认为这是无限循环。我的想法如下:
我们在sleep2()
之内调用sleep2(3)
个函数,然后在调用pause()
后,SIGALRM
将在3秒后发送。因此,将调用信号处理程序sig_alarm()
。
并且,在调用longjmp()
之后,它将转到sleep2中的setjmp()
函数。最后,在测试setjmp()
的返回值(调用longjmp()
后应为1)后,它将执行return alarm(0)
。因此,它会立即再次调用sig_alarm()
(因为SIGALRM
再次传递),并且此循环将继续。
我错过了什么?
答案 0 :(得分:2)
alarm(0)
不会发送任何警报事件。它取消先前安排的警报并返回此取消警报之前剩余的秒数(如果有)。
代码的最后一行不会导致无限循环,因为它不会执行sig_alarm
。它会将剩余的秒数返回到sleep2
的正常到期时间。在你的小例子中,这将是零。您的代码可能是较大软件的一部分,其中longjmp
(以及sleep2
的最后一行)可能在计时器到期之前执行。在这种情况下,sleep2
会返回正常到期的剩余秒数。