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

本文通过具体的代码示例,详细解析了Linux环境下如何使用pause函数和处理信号(如SIGINT和SIGALRM)。讨论了不同情况下信号处理函数的执行流程,包括如何利用longjmp实现信号间的跳转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值