当前位置:主页 > 查看内容

Linux-信号产生-注册-注销-处理方式

发布时间:2021-10-14 00:00| 位朋友查看

简介:文章目录 1. 信号的产生 1.1 硬件产生 1.2 软件产生 2. 信号的注册 3. 信号的注销 3.1 非可靠信号 3.2 可靠信号 4. 信号的处理方式 1. 信号的产生 1.1 硬件产生 ctrl c:SIGINT(2) ctrl z:SIGTSTP(20) ctrl |:SIGQUIT(3) ??如何查看信号的信息以及查看信号的……

1. 信号的产生

1.1 硬件产生

ctrl + c:SIGINT(2)
ctrl + z:SIGTSTP(20)
ctrl + |:SIGQUIT(3)

??如何查看信号的信息以及查看信号的默认处理动作?

man 7 signal

??操作系统对信号的处理动作:
在这里插入图片描述
??Term:终止
??Ign:忽略
??Core:终止+产生coredump文件
??Stop:停止
??Cont:继续

如果某一个信号的处理动作是“core”:
??1.默认是需要完成终止进程+产生coredump文件
??2.产生coredump文件,依赖ulimit -a==>“core file size”和磁盘大小
core file size 设置成为unlimited

信号具体的信息:信号的名称 + 信号的值(整数)+ action + 描述
在这里插入图片描述

1.2 软件产生

kill命令:
??kill [pid]可以终止一个进程
??kill -[num] [pid] :给进程号为pid的进程发送一个信号值为num的信号

kill函数
??int kill(pid_t pid, int sig);
??功能:给pid进程发送sig信号
??给自己发信号
eg:kill (getpid(),9)
??int raise(int sig);
??功能:谁调用给谁发送sig信号

2. 信号的注册

??1.一个进程收到一个信号,这个过程我们称之为注册。
??2.信号的注册和信号的注销并不是一个过程,是两个独立的过程。
??3.信号的注册分为两种情况,非可靠信号的注册和可靠信号的注册
在这里插入图片描述
??1.在操作系统内核“struct task_struct”结构体内部有一个变量:“struct sigpending pending”
??2.内核定义的结构体“struct sigpending”当中有两个变量:一个是内核定义的双向链表第二个是:sigset_t signal
??3.内核定义的类型“sigset_t”为一个结构体,在结构体内部有一个变量,该变量为一个数组,是无符号长整型的数组
??unsigned long sig[_NSIG_WORDS];

??1.信号的注册本质上就是在使用sig数组,但是并不是按照数组类型的方式在使用,而是按照位图(比特为)的方式在使用:
??eg:某一个信号注册,则将某一个信号对应的比特位置为1
??2.sig数组的比特位个数远远大于62,剩余的比特位为保留位
????struct sigpending ==> sigset_t signal ==> sig[xxx]
??一般在信号注册的时候,称之为操作sig位图(sig[xxx]),内核当中对于注册的时候,还有一个sigqueue队列,信号的注册逻辑位,将信号对应的sig位图当中的比特位置为1,并且在sigqueue队列当中添加一个sigqueue节点;通过注册第一个信号两次,来区分可靠信号和非可靠信号的注册逻辑。

非可靠信号的注册:
第一次:
??1.更改信号对应在sig位图当中的比特位(0–1)
??2.在sigqueue队列当中添加sigqueue节点
第二次:
??1.更改信号对应的sig位图当中的比特位(1–1)
??2.对于第二次的信号,不添加sigqueue节点到sigqueue队列当中
注意:
??如果有多个同一个信号来注册,那么对于非可靠信号而言,只会添加一次sigqueue节点,换言之,只注册了一次。

可靠信号的注册:
第一次:
??1.更改信号对应在sig位图当中的比特位(0–1)
??2.在sigqueue队列当中添加sigqueue节点
第二次:
??1.更改sig位图(1–1)
??2.在sigqueue队列当中添加sigqueue节点
注意:
??如果有多次同一个可靠信号来注册,那么对于可靠信号而言,会添加多次sigqueue节点,换言之,会注册多次

3. 信号的注销

3.1 非可靠信号

??1.将信号对应到sig位图当中的比特位置为0
??2.将对应的非可靠信号的sigqueue节点进行出队操作

3.2 可靠信号

??1.先将可靠信号对应的sigqueue进行出队操作
??2.判断sigqueue队列当中是否有同类的可靠信号的sigqueue节点,如果有,不会将sig位图当中对应的比特位置为0,如果没有,将sig位图当中对应的比特位置为0

在这里插入图片描述

4. 信号的处理方式

默认处理方式: 在操作系统内核当中定义好了
??宏:SIG_DFL
忽略处理方式: 操作系统定义进程收到某一个信号之后,忽略掉(进程即使收到了某个信号,进程也不会做任何事情)
??宏:SIG_IGN
??eg:僵尸进程:子进程先于父进程退出,子进程会向父进程发送SIGCHLD信号,父进程对SIGCHLD信号是忽略处理的,所以父进程并不会做任何事情,导致子进程的资源没有进程进行回收,从而子进程变成僵尸进程
自定义处理方式:
??1.程序员可以定义某一个信号的处理方式
??2.函数
??typedef void (*sighandler_t)(int);
??sighandler_t signal(int signum,sighandler_t handler);
??signum:待要更改的信号的值
??handler:函数指针,接收一个函数的地址,这个函数没有返回值,有一个int类型的参数自定义signum这个信号的处理方式,定义为handler这个函数指针保存的函数地址对应的函数,换句话说,当进程收到signum这个信号的时候,就会调用handler当中保存的函数。

代码
在这里插入图片描述
现象
在这里插入图片描述
??1.signal函数向内核注册了一个信号的处理函数,调用signal函数的时候,并没有调用注册的函数(注册的函数在进程收到进程之后才调用),这种方式称之为“回调”。
??int sigaction(int signum, const struct sigaction *act, struct sigaction * oldact);
??signum:待要自定义处理的信号
??act:要将信号处理方式更改为act
??oldact:原来的处理方式

struct sigaction
{
	void (*sa_hander)(int);//保存信号默认函数处理方式的函数指针
	void (*sa_sigaction)(int, siginfo_t * , void *);//函数指针,但是这个函数指针需要配合sa_flags一起使用,当sa_flags当中的值为SA_SIGINFO的时候,信号处理是按照“sa_sigaction”当中保存的函数地址来处理的
	sigset_t sa_mask;//当进程在处理某一个信号的时候,有可能还会收到其他的信号,此时,其他的信号就暂时存在sa_mask当中。
	int sa_flags;
	void (*sa_restorer)(void);//保留字段
};
;原文链接:https://blog.csdn.net/weixin_43580319/article/details/115984746
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!
上一篇:Unidbg调用崔庆才app练习9题so计算token 下一篇:没有了

推荐图文


随机推荐