1. 内核与用户空间信号交互的本质
当我们在Linux系统中谈论"内核与用户_信号"时,实际上是在讨论操作系统最核心的进程间通信机制。信号(Signal)作为Unix/Linux系统中历史最悠久的进程间通信方式之一,其本质是内核向用户进程发送的一个异步事件通知。
信号的特殊性在于它跨越了内核态与用户态的边界。当硬件中断触发或系统调用执行时,CPU会从用户态切换到内核态,此时内核拥有完全的系统控制权。而信号的传递正是利用这种特权级切换的机会,在内核态完成信号队列的维护,再在返回用户态时触发信号处理。
2. 信号处理的核心机制
2.1 信号的生命周期
一个典型的信号处理流程包含以下阶段:
- 信号产生:由内核或另一个进程触发(如kill系统调用)
- 信号递送:内核将信号加入目标进程的信号队列
- 信号处理:进程从内核态返回用户态时检查并处理信号
- 信号清除:处理完成后清除信号标记
这个过程中最关键的阶段是内核态到用户态的切换点,此时内核会检查当前进程的signal->pending信号队列。如果发现有待处理信号,就会先处理信号再返回到用户空间被中断的代码位置。
2.2 内核中的信号数据结构
在内核源码中,每个进程的task_struct都包含关键的信号相关字段:
c复制struct task_struct {
// ...
struct signal_struct *signal;
struct sighand_struct *sighand;
sigset_t blocked;
sigset_t real_blocked;
struct sigpending pending;
// ...
};
其中:
signal:进程信号处理的整体状态sighand:信号处理函数表blocked:被阻塞的信号掩码pending:待处理的信号队列
当内核需要向进程发送信号时,最终会调用__send_signal()函数将信号加入目标进程的pending队列:
c复制static int __send_signal(int sig, struct kernel_siginfo *
