C - Longjmp,setjmp 的无限循环


#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返回正常过期的剩余秒数。

最新更新