信号基本概念
- 软件中断,打断正在运行的进程,使之去处理信号
信号种类
- 62种
- 1-31 : 不可靠信号, 有可能会丢失, 不是实时信号
- 34-64 : 可靠信号, 实时信号
信号的生命周期
信号的产生:
-
- 硬件产生
- ctrl + c : 给前台程序发送 SIGINT
- ctrl + z : 给前台进程发送 SIGTSTP
- ctrl + | : 给前台进程发送 SIGQUIT
- 软件的产生
- kill [pid] 给进程发送 SIGTERM
- kill -signal pid
- 调用函数
- kill(int pid, int signal);
- abort() 谁调用给谁发送 SIGABRT 信号
- int alarm(uint seconds);发送 SIGALRM 信号
- 6号信号, double free (内存越界,没有产生段错误,free一次就会产生);11号 解引用空指针, 内存访问越界;
- 硬件产生
信号的注册(sched.h):
-
- PCB -> pending(结构体) ->signal(数组,位图)对应位置为1
- 非可靠信号的注册
- 更改sig位图, 然后再sigqueue队列中添加对应信号的节点,如果该信号的位图对应的bit位已经置为1了, 则不再向队列中添加节点, 即这个信号被丢弃掉了
- 可靠信号的注册
- 再次收到相同可靠信号时, 再向sigqueue中添加对应信号的节点
- 信号的注销:
- 不可靠信号的注销 : 将sig位图当中对应bit位变成0, 拿出sigqueue中对应的节点,执行操作
- 可靠信号的注销 : 拿出sigqueue中对应的节点,执行操作,如果队列中还有相同的节点, 则信号对应的bit为不置为 0,
信号的处理:
- 默认处理方式
- 忽略处理方式
- 自定义的处理方式
- signal函数:可以重置当前操作系统对信号的处理方式
- sighandler_t signal(int signum, sighandler_t handler)
- sighandler_t 函数指针void(*)(int)
- 9号和19号不可以被修改处理方式的
- sigaction:
- int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
- PCB中的 sighand_struct指针 -->sighand_struct -> struct k_sigaction 数组每个元素对应一个信号处理逻辑 -> struct k_sigaction -> struct sigaction -> sighandler_t handler 函数指针
- signal函数:可以重置当前操作系统对信号的处理方式
- 原理:
- signal:改变了 handler 指针指向的函数
- sigaction : 改变 k_sigaction
- signal底层调用sigaction函数
信号的捕捉
- 当执行系统调用,程序异常时,进入内核
信号阻塞
- block:位图 对应bit位为 1 则阻塞(9号19号信号不会被阻塞)
- int sigprocmask(int how, const sigset_t* set, sigset_t* old)
- how:何种方式使用这个函数
- SIG_BLOCK : 设置某个信号为阻塞状态 new = old | set
- SIG_UNBLOCK : 设置某个信号为非阻塞状态 new = old & (~set)
- SIG_SETMASK : 设置新的位图 new = set
- how:何种方式使用这个函数
重入
- 竞态条件: 不同的执行流执行顺序不同,会得到不同的结果
- 可重入: 不同执行流操作同一份资源, 不会对结果产生影响结果
- 不可重入: ---------------------------------, 会产生影响
- 全局变量
- malloc free
- STL大部分容器
- volatile