unix环境高级编程-alarm、pause()与信号处理函数

68 篇文章 0 订阅
panse()要等信号处理完成后才能返回,遇到信号,linux会中断当前任务跳转去执行信号处理,处理完成再跳转回中断的地方继续。这段代码是《unix环境高级编程》中摘的,运行时按下ctrl+c,程序收到(ctrl+c产生的中断)信号,跑去执行sig_int函数,如果执行sig_int函数中途有遇到alarm产生的闹钟信号,又中断当前sig_int的任务,跑去sig_alrm函数,
若sig_alrm中没有跳转jmp就等sig_alrm执行完成就跑回sig_int中断处继续,sig_int完了,pause()返回,main继续。
若是有跳转jmp,那就跟着jmp走以前的就不管了,不跳回去了。
#include  
   
   
    
    
#include  
    
    
     
     
#include  
     
     
      
      
#include  
      
      
       
       
#include  
       
       
         static jmp_buf env_alrm; //若启用jmp跳转,与函数sig_int中的循环 //则不会有 printf("\nline 39:sig_int finished\n");因为按下ctl+c中断时, //程序中断当前任务(睡眠),跑去调用sig_int函数处理, //sig_int函数处理【完成后】,25行的【pause()才能返回】, //但是sig_int处理时间长于5秒,alarm时间到了,程序从sig_int中断跑去 //执行sig_alrm函数,当启用longjmp时程序就不会跳转回以前中断的地方继续了, //导致sig_int函数中断后没有继续,运行结果: //[root@localhost code]# ./alarm.o //^C ctrl+c 中断 //line 31:sig_int starting:pid=2585 //line 11:sig_alrm pid=2585 //line 25 exit sleep2 //line 50:main-sleep2 returned:unslept=0;pid=2585 static void sig_alrm(int signo) { printf("line 11:sig_alrm pid=%d\n",getpid()); //sleep(3); // longjmp(env_alrm,1); } unsigned int sleep2(unsigned int nsecs) { if(signal(SIGALRM,sig_alrm)==SIG_ERR) return(nsecs); // if(setjmp(env_alrm)==0) // { alarm(nsecs); pause(); // } printf("line 25 exit sleep2\n"); return(alarm(0)); } static void sig_int(int signo) { volatile int k; int i,j; printf("\nline 31:sig_int starting:pid=%d\n",getpid()); //若注释掉这段循环,运行结果 //[root@localhost code]# ./alarmAndPause.o //line 31:sig_int starting:pid=2452 //^C 运行一秒时ctrl+c 中断 //line 39:sig_int finished //line 25 exit sleep2 //line 50:main-sleep2 returned:unslept=4;pid=2452 //因为闹钟时间还没到 //所以没有打印sig_alrm中的 printf("line 11:sig_alrm pid=%d\n",getpid()); for(i=0;i<500000;i++)//要使循环运行时间大于五秒 { for( j=0 ; j<10000;j++ ) { k+=i*j; //printf("line 37:loop i=%d;j=%d;k=%d\n",i,j,k); } } printf("\nline 39:sig_int finished\n"); } int main(int argc, char *argv[]) { unsigned int unslept; if(signal(SIGINT,sig_int)==SIG_ERR) { printf("signal(sigint) err\n"); exit(-1); } unslept=sleep2(5); printf("line 50:main-sleep2 returned:unslept=%u;pid=%d\n",unslept,getpid()); exit(0); } 
       
      
      
     
     
    
    
   
   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值