Browse Source

新增signal文档 (#126)

* 新增signal文档
login 2 years ago
parent
commit
9983902105
3 changed files with 93 additions and 0 deletions
  1. 1 0
      docs/index.rst
  2. 10 0
      docs/kernel/ipc/index.rst
  3. 82 0
      docs/kernel/ipc/signal.md

+ 1 - 0
docs/index.rst

@@ -22,6 +22,7 @@
    kernel/locking/index
    kernel/process_management/index
    kernel/sched/index
+   kernel/ipc/index
    kernel/memory_management/index
    kernel/filesystem/index
    kernel/debug/index

+ 10 - 0
docs/kernel/ipc/index.rst

@@ -0,0 +1,10 @@
+====================================
+进程间通信
+====================================
+
+   这里是DragonOS进程间通信(IPC)的说明文档。
+   
+.. toctree::
+   :maxdepth: 1
+
+   signal

+ 82 - 0
docs/kernel/ipc/signal.md

@@ -0,0 +1,82 @@
+# Signal信号
+
+:::{note}
+本文Maintainer: 龙进
+
+Email: <[email protected]>
+:::
+
+&emsp;&emsp;信号是一种进程间通信机制,当我们发送一个信号给特定的进程,就能触发它的特定行为(例如退出程序,或者运行一些信号处理程序)。信号是发送到进程或同一进程内的特定线程的异步通知,用于通知它有事件发生。信号的常见用途是中断、挂起、终止或终止进程。发送信号时,操作系统会中断目标进程的正常执行流程以传递信号。可以在任何非原子指令期间中断执行。如果该进程之前注册了一个信号处理程序,则执行该例程。否则,将执行默认信号处理程序。
+
+&emsp;&emsp;信号类似于中断,区别在于中断由CPU调解并由内核处理,而信号在内核中产生(也可通过系统调用让内核产生)并由各个进程或内核的默认处理函数处理。
+
+## 1.信号处理概要
+
+### 1.1 信号发送
+
+&emsp;&emsp;当进程A想发送信号给进程B的时候,使用`kill(pid, signal)`接口进行发送。然后陷入内核的`sys_kill()`函数中进行处理。然后内核将会把信号加入目标进程的pcb的`sigpending`中。
+
+示意图如下:
+
+```text
+   ┌────────────┐
+   │ Process A: │
+   │            │
+   │  sys_kill  │
+   └──────┬─────┘
+          │
+          │
+   ┌──────▼──────┐    ┌────────────────────┐
+   │ Send Signal ├────►Add to sigpending of│
+   └─────────────┘    │   process B.       │
+                      └────────────────────┘
+
+```
+
+### 1.2 信号处理
+
+&emsp;&emsp;进程会在退出内核态的时候,跳转到`do_signal()`函数内,检查当前是否有需要被处理的信号,如果有的话,就会开启信号处理流程。
+
+信号处理流程示意图:
+
+```text
+
+ ┌───────────────────────┐
+ │       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. 其他问题
+
+&emsp;&emsp;暂无。