- 论坛徽章:
- 0
|
3可用积分
这是APUE2中程序清单10_6。
APUE2中说当SIGALRM信号中断了其它信号处理程序,则调用longjmp函数会提早终止该信号处理程序。
在本程序中,当程序开始运行后,按下ctrl+c产生SIGINT信号,main捕捉到该信号后调用sig_int处理函数(这个
函数运行的时间超过5s),而程序运行5s后,sleep2函数产生SIGALRM信号,被sig_alrm信号处理程序捕捉到后,该
程序调用longjmp,按照APUE2说的意思,这个SIGALRM信号中断了sig_int信号处理程序(为什么会中断该信号处理
程序呢?SIGALRM信号系统默认动作是终止程序,但是在sleep2中已经捕捉了该信号改变了它的默认处理动作了阿),而它
调用了longjmp函数会终止sig_int信号处理程序,这里我就不明白了,sig_int函数是SIGALRM终止的呢还是longjmp终止的呢?
这里SIGALRM信号被捕捉已经不会终止进程了,而longjmp函数好像也没有终止进程的功能吧?
- #include <stdio.h>
- #include <stdlib.h>
- #include <setjmp.h>
- #include <signal.h>
- #include <unistd.h>
- static jmp_buf env_alrm;
- static void sig_alrm(int signo);
- static void sig_int(int signo);
- unsigned int sleep2(unsigned int nsecs);
- static void sig_alrm(int signo)
- {
- longjmp(env_alrm, 1);
- }
- unsigned int sleep2(unsigned int nsecs)
- {
- if(signal(SIGALRM, sig_alrm) == SIG_ERR){
- perror("signal error");
- exit(1);
- }
- if(setjmp(env_alrm) == 0){
- alarm(nsecs);
- pause();
- }
- return alarm(0);
- }
- static void sig_int(int signo)
- {
- int i, j;
- volatile int k;
- printf("caught SIGINT!\n");
- // sleep(10);
- for(i = 0; i < 10000000; i++){
- for(j = 0; j < 10000; j++){
- k += i * j;
- }
- }
- printf("after sig_int!\n");
- }
- int main(int argc, char** argv)
- {
- unsigned int unslept;
- if(signal(SIGINT, sig_int) == SIG_ERR){
- perror("signal error");
- exit(2);
- }
- unslept = sleep2(5);
- printf("sleep2 returned : %d\n", unslept);
- exit(0);
- }
复制代码
[ 本帖最后由 xiaozhu2007 于 2007-12-27 00:22 编辑 ] |
最佳答案
查看完整内容
我试着给你解释一下。sig_int函数应该是longjmp终止的。因为当调用longjmp时,它跳转到slee2函数中,这样它把sig_int的栈帧给跳了过去,sig_int函数就莫名的结束的。你做一下习题10.3,如果对栈帧不太了解,参考setjmp和longjmp那一节。
|