# Signal信号 — DragonOS dev 文档

# Signal信号

备注

本文Maintainer: 龙进

Email: longjin@RinGoTek.cn

信号是一种进程间通信机制，当我们发送一个信号给特定的进程，就能触发它的特定行为（例如退出程序，或者运行一些信号处理程序）。信号是发送到进程或同一进程内的特定线程的异步通知，用于通知它有事件发生。信号的常见用途是中断、挂起、终止或终止进程。发送信号时，操作系统会中断目标进程的正常执行流程以传递信号。可以在任何非原子指令期间中断执行。如果该进程之前注册了一个信号处理程序，则执行该例程。否则，将执行默认信号处理程序。

信号类似于中断，区别在于中断由CPU调解并由内核处理，而信号在内核中产生（也可通过系统调用让内核产生）并由各个进程或内核的默认处理函数处理。

## 1.信号处理概要

### 1.1 信号发送

当进程A想发送信号给进程B的时候，使用`kill(pid, signal)`接口进行发送。然后陷入内核的`sys_kill()`函数中进行处理。然后内核将会把信号加入目标进程的pcb的`sigpending`中。

示意图如下：

       ┌────────────┐
       │ Process A: │
       │            │
       │  sys_kill  │
       └──────┬─────┘
              │
              │
       ┌──────▼──────┐    ┌────────────────────┐
       │ Send Signal ├────►Add to sigpending of│
       └─────────────┘    │   process B.       │
                          └────────────────────┘

### 1.2 信号处理

进程会在退出内核态的时候，跳转到`do_signal()`函数内，检查当前是否有需要被处理的信号，如果有的话，就会开启信号处理流程。

信号处理流程示意图：

     ┌───────────────────────┐
     │       Process B:      │
     │                       ◄─────────────────────────────────┐
     │ Return from syscall...│                                 │
     └─────────┬─────────────┘                                 │
               │                                               │
               │                                               │
               │                ┌────────────────┐             │
         ┌─────▼─────┐ default  │                │             │
         │ do_signal ├────────► │ stop process B.│             │
         └─────┬─────┘  action  │                │             │
               │                └────────────────┘             │
               │ custom action                                 │
        ┌──────▼───────┐                                       │
        │ setup signal │                                       │
        │    frame     │                                       │
        └──────┬───────┘                                       │
               │jump to                                        │
        ┌──────▼───────┐ ┌────────────┐ sys_sigreturn ┌────────┴────────┐
        │   userland   ├─►sa_restorer ├──────────────►│Restore the stack│
        │ sig handler  │ └────────────┘               │    frame.       │
        └──────────────┘                              └─────────────────┘

- 如果内核检查发现，进程没有指定信号处理函数，且信号处理动作不是“忽略”，那就会杀掉进程。

- 如果内核发现该信号没有被忽略，那么将会：

  - 备份当前内核栈

  - 设置信号处理的用户态栈帧

  - 回到用户态，执行信号处理函数

  - 信号处理函数结束之后，将会进入由libc提供的__sa_restorer中，发起`sys_sigreturn()`系统调用，回到内核态

  - 内核恢复处理信号之前的内核栈。

  - 信号处理流程结束，内核继续执行“返回用户态”的过程。

- 如果内核发现当前信号被忽略，那么就检查下一个信号。

- 发现没有任何需要处理的信号时，返回用户态。

## 2. 其他问题

暂无。

Other Versions v: V0.2.0

Tags
  V0.1.0
  V0.1.1
  V0.1.10
  V0.1.2
  V0.1.3
  V0.1.4
  V0.1.5
  V0.1.6
  V0.1.7
  V0.1.8
  V0.1.9
  V0.2.0
  V0.3.0
  V0.4.0

Branches
  master