信号例子
信号: 信号是进程之间事件异步通知的一种方式,属于软中断。
使用kill -l 命令查看系统定义的信号列表
信号处理的常见方式
产生信号
通过终端按键产生信号
core dump
调用系统函数像进程发信号
软件条件产生信号
硬件异常产生信号
硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的指令,cpu的运算单元会产生异常,内核将这个异常解释 为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。
信号捕捉初识
思考
- 所有信号产生,最终要有OS来进行执行,因为OS是进程的管理者。
- 信号不是立即处理的,而是在合适的时候处理? 什么时候合适。
- 信号如果不是被立即处理,那么信号是否需要被进程记录下来?记录在何处合适?
- 一个进程在没有接收到信号额时候,能否知道自己应该对合法信号作何处理呢?
- 如何理解OS向进程发送信号?描述下处理过程。
阻塞信号
- 实际执行信号的处理动作称为信号的递达(Delivery)。
- 信号从产生到递达之间的状态称之为未决(Pending)。
- 进程可以选择阻塞(Block)某个信号。
- 被阻塞的信号产生将保持在未决状态,直到进程解除对此信号的阻塞,才能执行递达的动作。
- 注意,阻塞呵忽略是不同的,只要信号被阻塞就不会被递达,而忽略是在递达之后可选的一种处理动作。
在内核角度
sigset_t
信号集操作函数
这四个函数都是成功返回0,出错返回-1。sigismember是一个布尔函数,用于判断一个信号集的有效信号中是否包含某种 信号,若包含则返回1,不包含则返回0,出错返回-1
sigprocmask
调用函数 sigprocmask 可以读取或更改进程的信号屏蔽字(阻塞信号集)。
sigpending
信号捕捉
内核如何实现信号的捕捉
如果信号处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号。由于信号处理函数的代码在用户空间,处理过程比较复杂,举例如下: 用户注册了SIGQUIT信号的处理函数sighandler. 当前正在指向main函数,这时发生中断或者异常切换到内核态。在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达。内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函数,sighandler和main函数使用不同的堆栈空间,他们之间不存在调用和被调用的关系,而是两个独立的执行流程。sighandler 函数返回后,自动执行特殊的系统调用sigreturn 再次进入内核态。如果没有新的信号要递达,这次再返回用户态就是恢复main函数的上下文继续执行。
sigaction
当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字,这样就保证了在处理某个信号时,如果这种信号再次产生,那么 它会被阻塞到当前处理结束为止。 如果在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字。 sa_flags字段包含一些选项,本章的代码都把sa_flags设为0,sa_sigaction是实时信号的处理函数。
可重入函数
volatile
SIGCHLD 信号
原文地址:https://www.jb51.cc/wenti/3287809.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。