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