1、信号
执行命令 kill -l 查看信号列表
信号分为两类:普通信号(1-31)、实时信号(34-64)
注意:大部分情况下信号不会立刻执行,大部分情况下信号是默认终止程序的,信号会在合适的时候执行。
2、信号的产生
产生方式有:按键、异常(内存越界、除零)、指令、调用系统函数
1)按键:
用户在终端按下某些键时,终端驱动程序会发送信号给前台进程,例如Ctrl-C产生SIGINT信
号,Ctrl-\产生SIGQUIT信号,Ctrl-Z产生SIGTSTP信号。
什么是core dumped?
当一个进程要异常终止时,可以选择把进程的用户空间内存数据全部保存到磁盘上,文件名通常是core,这叫做Core Dump。进程异常终止通常是因为有Bug,比如非法内存访问导致段错误,事后可以用调试器检查core文件以查清错误原因,这叫做Post-mortem Debug(事后调试)。一个进程允许产生多大的core文件取决于进程的Resource Limit(这个信息保存在PCB中)。默认是不允许产生core文件的,因为core文件中
可能包含用户密码等敏感信息,不安全。
可以通过命令来修改限制:
先编写一段死循环程序,用Ctrl—\来终止程序,查看core文件的大小
程序为:
结果为:
2)异常:
硬件异常产生信号,这些条件由硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。
3)调用系统函数:
首先在后台执行死循环程序,然后用kill命令给它发SIGSEGV信号。(命令后面加&,前台进程转为后台进程)
3、信号的处理
处理方式由三种,分别是:
1)忽略此信号
2)执行默认动作
3)执行自定义的函数
4、阻塞信号
执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending)。进程可以选择阻塞(Block )某个信号。被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后 可选的一种处理动作。
信号在内核中的示意图:
5、信号集操作函数:
函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表示该信号集不包含任何有效信号。函数sigfillset初始化set所指向的信号集,使其中所有信号的对应bit置位,表示该信号集的有效信号包括系统支持的所有信号。注意,在使用sigset_t类型的变量之前,一定要调用sigemptyset或sigfillset做初始化,使信号集处于确定的状态。初始化sigset_t变量之后就可以 在调用sigaddset和sigdelset在该信号集中添加或删除某种有效信号。这四个函数都是成功返回0,出错返回-1。sigismember是一个布尔函数,用于判断一个信号集的有效信号中是否包含某种信号,若包含则返回1,不包含则返回0,出错返回-1。
下面一段程序是函数的使用举例:
程序:
结果分析:
转载于:https://blog.51cto.com/lovemeright/1825740