1*99839021Slogin# Signal信号 2*99839021Slogin 3*99839021Slogin:::{note} 4*99839021Slogin本文Maintainer: 龙进 5*99839021Slogin 6*99839021SloginEmail: <longjin@RinGoTek.cn> 7*99839021Slogin::: 8*99839021Slogin 9*99839021Slogin  信号是一种进程间通信机制,当我们发送一个信号给特定的进程,就能触发它的特定行为(例如退出程序,或者运行一些信号处理程序)。信号是发送到进程或同一进程内的特定线程的异步通知,用于通知它有事件发生。信号的常见用途是中断、挂起、终止或终止进程。发送信号时,操作系统会中断目标进程的正常执行流程以传递信号。可以在任何非原子指令期间中断执行。如果该进程之前注册了一个信号处理程序,则执行该例程。否则,将执行默认信号处理程序。 10*99839021Slogin 11*99839021Slogin  信号类似于中断,区别在于中断由CPU调解并由内核处理,而信号在内核中产生(也可通过系统调用让内核产生)并由各个进程或内核的默认处理函数处理。 12*99839021Slogin 13*99839021Slogin## 1.信号处理概要 14*99839021Slogin 15*99839021Slogin### 1.1 信号发送 16*99839021Slogin 17*99839021Slogin  当进程A想发送信号给进程B的时候,使用`kill(pid, signal)`接口进行发送。然后陷入内核的`sys_kill()`函数中进行处理。然后内核将会把信号加入目标进程的pcb的`sigpending`中。 18*99839021Slogin 19*99839021Slogin示意图如下: 20*99839021Slogin 21*99839021Slogin```text 22*99839021Slogin ┌────────────┐ 23*99839021Slogin │ Process A: │ 24*99839021Slogin │ │ 25*99839021Slogin │ sys_kill │ 26*99839021Slogin └──────┬─────┘ 27*99839021Slogin │ 28*99839021Slogin │ 29*99839021Slogin ┌──────▼──────┐ ┌────────────────────┐ 30*99839021Slogin │ Send Signal ├────►Add to sigpending of│ 31*99839021Slogin └─────────────┘ │ process B. │ 32*99839021Slogin └────────────────────┘ 33*99839021Slogin 34*99839021Slogin``` 35*99839021Slogin 36*99839021Slogin### 1.2 信号处理 37*99839021Slogin 38*99839021Slogin  进程会在退出内核态的时候,跳转到`do_signal()`函数内,检查当前是否有需要被处理的信号,如果有的话,就会开启信号处理流程。 39*99839021Slogin 40*99839021Slogin信号处理流程示意图: 41*99839021Slogin 42*99839021Slogin```text 43*99839021Slogin 44*99839021Slogin ┌───────────────────────┐ 45*99839021Slogin │ Process B: │ 46*99839021Slogin │ ◄─────────────────────────────────┐ 47*99839021Slogin │ Return from syscall...│ │ 48*99839021Slogin └─────────┬─────────────┘ │ 49*99839021Slogin │ │ 50*99839021Slogin │ │ 51*99839021Slogin │ ┌────────────────┐ │ 52*99839021Slogin ┌─────▼─────┐ default │ │ │ 53*99839021Slogin │ do_signal ├────────► │ stop process B.│ │ 54*99839021Slogin └─────┬─────┘ action │ │ │ 55*99839021Slogin │ └────────────────┘ │ 56*99839021Slogin │ custom action │ 57*99839021Slogin ┌──────▼───────┐ │ 58*99839021Slogin │ setup signal │ │ 59*99839021Slogin │ frame │ │ 60*99839021Slogin └──────┬───────┘ │ 61*99839021Slogin │jump to │ 62*99839021Slogin ┌──────▼───────┐ ┌────────────┐ sys_sigreturn ┌────────┴────────┐ 63*99839021Slogin │ userland ├─►sa_restorer ├──────────────►│Restore the stack│ 64*99839021Slogin │ sig handler │ └────────────┘ │ frame. │ 65*99839021Slogin └──────────────┘ └─────────────────┘ 66*99839021Slogin 67*99839021Slogin``` 68*99839021Slogin 69*99839021Slogin- 如果内核检查发现,进程没有指定信号处理函数,且信号处理动作不是“忽略”,那就会杀掉进程。 70*99839021Slogin- 如果内核发现该信号没有被忽略,那么将会: 71*99839021Slogin - 备份当前内核栈 72*99839021Slogin - 设置信号处理的用户态栈帧 73*99839021Slogin - 回到用户态,执行信号处理函数 74*99839021Slogin - 信号处理函数结束之后,将会进入由libc提供的__sa_restorer中,发起`sys_sigreturn()`系统调用,回到内核态 75*99839021Slogin - 内核恢复处理信号之前的内核栈。 76*99839021Slogin - 信号处理流程结束,内核继续执行“返回用户态”的过程。 77*99839021Slogin- 如果内核发现当前信号被忽略,那么就检查下一个信号。 78*99839021Slogin- 发现没有任何需要处理的信号时,返回用户态。 79*99839021Slogin 80*99839021Slogin## 2. 其他问题 81*99839021Slogin 82*99839021Slogin  暂无。 83