Linux--信号

对于 linux来说,信号是软中断。许多重要的程序都需要处理信号。信号,为linux提供了一种处理异步事件的方法。比如,终端用户输入了ctrl+c来中断程序,会通过信号机制停止一个程序。

一、信号概述:
1、信号的名字和编号:
每个信号都有一个名字和编号,名字都以SIG开头。
信号定义在 signal.h,头文件中,信号名都定义为正整数。
信号是从1开始编号的,不存在0号信号。
使用kill -l来查看信号的名字以及序号。kill对0信号有特殊应用。
编号1-64:

 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	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

2、信号处理的方式:
(忽略,捕捉,默认动作)

忽略信号:
大多数信号可以使用这个方式来处理。但是 SIGKILL和SIGSTOP信号无法忽略。
捕捉信号:
需要高速内核,用户希望如何处理某一种信号,说白了就是写一个信号处理函数,然后将这个函数高速内核。当该信号产生时,由内核来调用用户自定义的函数,以此来实现某种信号的处理。
系统默认动作:
对于每个信号来说,系统对应默认的处理动作,当发生了该信号,系统会自动执行。

具体的信号默认动作可以使用man 7 signal 来查看系统的具体定义。
kill命令就是一个发送信号的工具
kill 9 PID:杀死进程
kill -SIGKILL PID:杀死进程
(使用ps指令来查看pid号:ps -aux|grep 运行的程序)

二、信号处理函数的注册
信号处理函数的注册不只是一种方法,分为入门版和高级版
1、入门版:函数signal
2、高级版:函数sigaction

#include <signal.h>
 
typedef void (*sighandler_t)(int);
 //指针返回void类型,参数为整型数,sighandler_t函数名
sighandler_t signal(int signum, sighandler_t handler);
//信号,指针,

三、信号处理函数的发送
信号处理函数的发送也不止一个,也分为入门版和高级版
1、入门版:kill
2、高级版:sigqueue

#include <sys/types.h>
#include <signal.h>
 
int kill(pid_t pid, int sig);

例:
实现信号,ctrl+c,关闭不了进程

#include <signal.h>
#include <stdio.h>
 
void handler(int signum)
{
	printf("get signal=%d\n",signum);
	switch(signum){
		case 2:
			printf("SIGINT\n");
			break;
		case 9:
			printf("SIGKILL");
			break;
		case 10:
			printf("SIGUSR1");
			break;
	}
	
	printf("never quit !\n");
}
 
int main()
{
	
	signal(SIGINT,handler);
	signal(SIGKILL,handler);
	signal(SIGUSR1,handler);
 
	while(1);
 
	return 0;
}

结果:

^Cget signal=2    //按CTRL+C得到
SIGINT
never quit !
^Cget signal=2
SIGINT
never quit !
get signum=10    //发送信号 kill -10 PID得到
SIGUSR1
never quit !
Killed           //发送信号 kill -9 PID得到

信号的发送程序:

//信号发送

#include <signal.h>
#include <sys/types.h>
#include <stdio.h>
 
int main(int argc,char **argv)
{
	int signum;
	int pid;
 
	/*方法二*/
	/*char cmd[128] = {0};*/
	
	signum = atoi(argv[1]);
	pid = atoi(argv[2]);
 
	printf("num = %d,pid = %d\n",signum,pid);
 
//int kill(pid_t pid, int sig);

	kill(pid,signum);
	
	/*sprintf(cmd,"kill -%d %d",signum,pid);作出一个指令 kill -9 xxxx
	system("cmd");
	*/
	
	printf("send signal ok !\n");

	return 0;
}

如何忽略信号:
SIG_IGN
修改代码:
signal(SIGINT,handler);为signal(SIGINT,SIG_IGN);文章来源地址https://uudwc.com/A/vmLBn

原文地址:https://blog.csdn.net/weixin_48208102/article/details/132896449

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

h
上一篇 2023年09月18日 02:24
Flutter插件的制作和发布
下一篇 2023年09月18日 02:28