关于linux中pause()函数的疑问

最近学习linux进程间通信时学习pause()函数,遇到点小疑问请教下大家:

首先,我看到这样一句话,pause捕获到信号将会直接终止进程。于是我进行了相关实验:

图片描述

最后的printf并没有打印。

但是,当我做了另一个实验,我产生了疑惑:

图片描述

这里,我的理解是:当alarm定时器走到第20s后,signal函数将会触发SIGALRM,然后调用func函数.


请问:
这里的pause捕获到信号为什么没有直接终止进程?(后面的printf打印了)

我不知道是否是应为sinal函数引起的或者是其他的原因,所以请教下大家。


源码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(){
    alarm(5);
    pause();
    printf("I have been awaken up \n");
}


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

void func(){
    printf("I have been awaken up\n");
    system("date");
}

int main(){
    signal(SIGALRM,func);
    system("date");
    alarm(20);
    pause();
    printf("why print???");
    return 0;
}
阅读 1.3k
评论
    3 个回答

    对于函数 unsigned int alarm(unsigned int seconds); 如果参数 seconds 大于 0,则 seconds 秒后,系统将向进程发送 SIGALRM 信号,该信号的默认行为是终止进程。

    对于函数 int pause(void); 作用是,将进程或线程休眠,直到收到信号导致进程被终止或被信号处理函数处理,对于后者,如果信号处理函数不退出进程,在调用信号处理函数之后,pause() 将返回,继续执行其后的程序。

    具体分析如下:

    第一个程序:

    int main(){
        alarm(5);
        pause();
        printf("I have been awaken up \n");
    }

    执行如下,

    1. 调用 alarm(5); 告诉系统,5s 后向进程发送 SIGALRM 信号
    2. 调用 pause(); 使进程处于休眠的状态
    3. 进程收到 SIGALRM 信号后,因为没有信号处理函数,该信号的默认行为是终止进程,所以进程退出

    第二个程序:

    void func(){
        printf("I have been awaken up\n");
        system("date");
    }
    
    int main(){
        signal(SIGALRM,func);
        system("date");
        alarm(20);
        pause();
        printf("why print???");
        return 0;
    }

    执行如下:

    1. 调用 signal(SIGALRM,func); 设置 SIGALRM 信号处理函数。
    2. 调用 system("date"); 打印日期
    3. 调用 alarm(20); 告诉系统,20s 后向进程发送 SIGALRM 信号
    4. 调用 pause(); 使进程处于休眠的状态
    5. 进程收到 SIGALRM 信号后,调用信号处理函数,func()
    6. 调用 printf("why print???"); 输出

    参见:

      • 9.6k

      man page 里写了。

      如果信号被截获并且信号处理函数返回了,那么 pause 就会返回,也就是不会终止进程。

        • 4.8k
        这里的pause捕获到信号为什么没有直接终止进程?
        1. “信号”会唤醒“挂起”状态的线程,但不能理解成 pause() 可以捕获信号。
        2. 两个例子区别在于,第一个进程没有被唤醒,而第二个进程被唤醒了。
        3. 为什么第一个进程没有被唤醒? 因为你没有重写 SIGALRM 信号的处理函数,默认情况下,该函数不会返回,它会终止进程,因此 pause() 后面的代码没有机会执行。
        4. 为什么第二个进程被唤醒? 因为你重写了 SIGALRM 信号的处理函数,并且该函数返回了,连带触发 pause()返回,进而执行后续代码。

        参考资料

          撰写回答

          登录后参与交流、获取后续更新提醒

          相似问题
          推荐文章