C语言的中断信号

信号:
中断信号 ----- 软中断(SIGSEGV)、硬中断(SIGINT ctrl+c)

gec@ubuntu:/$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS

1) SIGHUP  终端关闭时候内核发出的信号    默认是终止进程
2)SIGINT ctrl + c 终止
3: SIGQUIT ctrl+\ 终止 Quit (core dumped)
4: SIGABRT abort 终止 
9: SIGKILL 该信号才是杀死 kill -9 pid  终止  Killed (不能更改其默认处理方式)
10 12 :用户自定义功能的信号 忽略
11: SIGSEGV 段错误 终止
13:SIGPIPE 没有读端但是又去write的时候产生的   终止
14) SIGALRM  和alarm()函数配合,定时触发该信号 终止
15:SIGTERM 终止 (ctrl+ ?)
17: SIGCHLD 子进程退出时候内核产生的 忽略
19: SIGSTOP 进程暂停 stoped  (不能更改其默认处理方式) T    01:16   0:00 ./signal 可以再发送SIGCONT恢复运行

作用:
直接进行用户空间进程和内核进程间的交互 
内核进程利用信号来通知用户空间进程发生哪些系统事件


信号的发送
kill -INT 4980 
kill(pid , 信号)
raise(信号) ---- 发送个信号给本进程

信号的捕获:
signal(信号 , 信号处理函数(自定义函数 , SIG_DFL, SIG_IGN);

alarm  产生定时信号

alarm(0) ; 取消闹钟

alarm(10);   --- 10秒后会产生SIGALRM
如果10秒没有到,过了3秒又设置一个闹钟
int ltime  =  alarm(5);
这个时候ltime 就等于上个闹钟的剩余时间,7
如果没有正在跑的钟, 那alarm会返回0

sleep睡眠时候也能响应ALRM信号

pause 
pause();

等待捕获到进程中注册了信号处理函数的信号,进入的是sleep状态


实例:在父、子进程之间的信号处理

#include 
#include 
#include 
#include 

int global_var = 5;

void func(int sig)
{ 
	if(sig == SIGINT)
		printf("\n%d ) signal  is happened!\n", sig);
	printf("Ctrl+\\ or input q\n");

}

void func_1(int sig)
{ 
	if(sig == SIGINT)
		printf("\n%d ) signal  is happened!\n", sig);
	printf("Ctrl+\\ or input q\n");

}


int main(int argc, char **argv)
{
	pid_t pid;
	int var = 97;
	
	printf("before fork \n");// 缓冲方式
	
	if((pid=fork())< 0)
		perror("fork error"); //输出为: fork error : 出错原因描述 
	else if(pid ==0)// 只有子进程走
	{
		printf("child process pid = %d , ppid = %d \n",(int )getpid(),(int )getppid());
		global_var ++;
		var ++;
		// signal(SIGINT, func_1);
		/*
		这里子进程里如果没有捕获信号,那输入ctrl+c时就会结束掉子进程
		就结束了死循环的内容。
		如果这里也捕获了,那父、子进程各执行一次捕获的处理函数。
		然后输入q的话,是结束父进程,子进程会继续运行。这时要退出子进程,就用kill了。
		*/
		while(1)
		{
			sleep(2);
			// kill(getppid() , SIGUSR1);//子进程发送自定义的信号
			printf("this is a loop!waiting for Ctrl+C signal\n");	
		}
	}
	else// pid > 0  // 父进程,变量pid为子进程PID
	{
			signal(SIGINT, func);//捕获信号,也相当于注册信号的处理函数
			sleep(1);
			printf("parent process pid = %d , ppid = %d \n",(int )getpid(),(int )getppid());
			char s;
			while(1){
				scanf("%c",&s);
				if (s=='q')
				{
					exit(0);
				}
			}
			//这里要保持父进程没结束才能捕获信号。
			//因为2个进程都有while死循环,所以最下面的那句不执行了。
	}
	printf(" var = %d, global = %d \n\n",  var,global_var); // 父 、子进程都会调用

	 exit(0);
	
}

延时信号:

#include 
#include 
#include 
#include 

void func(int sig)
{
	printf("alarm returned 3 : %d \n",alarm(3));
}

void alarm_f(int sig)
{
	printf("\n%d ) signal  is happened!\n", sig);
	printf("alarm returned 2 : %d \n",alarm(10));
}


void main()
{
	signal(SIGALRM,alarm_f);/*注册SIGALRM的处理函数*/
	signal(SIGINT,func);/*注册SIGINT的处理函数*/
	printf("alarm returned 1 : %d \n",alarm(5));
	while(1)
	{
		printf("waiting ...\n");
		//sleep(10);/*sleep 1S */
		pause();
	}
	/*
	alarm是延多少时,然后执行alarm的中断信号,返回的是剩下的秒数
	pause是让目前的进程暂停,等到中断信号来了,再继续。
	所以waiting...不会一直输出。是等到有中断信号来了再输出
	reference:http://c.biancheng.net/cpp/html/334.html
	*/
	exit(0);
}




你可能感兴趣的:(C/C++)