ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

linux 进程信号(下)

linux 进程信号(下) Linux进程信号——捕捉、操作系统运行机制与实战四、捕捉信号4.1 信号捕捉的流程如果信号的处理动作是用户自定义函数在信号递达时就调用这个函数这称为捕捉信号。处理过程举例用户程序注册了SIGQUIT信号的处理函数sighandler当前正在执行main函数这时发生中断或异常切换到内核态在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达内核决定返回用户态后不是恢复main函数的上下文继续执行而是执行sighandler函数sighandler和main函数使用不同的堆栈空间它们之间不存在调用和被调用的关系是两个独立的控制流程sighandler函数返回后自动执行特殊的系统调用sigreturn再次进入内核态如果没有新的信号要递达这次再返回用户态就是恢复main函数的上下文继续执行了示意图用户态 -------------------------------- | | | | | | | | 内核态 -------------------------------- 检查pending表4.2 sigaction#includesignal.hintsigaction(intsigno,conststructsigaction*act,structsigaction*oact);sigaction函数可以读取和修改与指定信号相关联的处理动作。调用成功则返回0出错则返回-1signo是指定信号的编号若act指针非空则根据act修改该信号的处理动作若oact指针非空则通过oact传出该信号原来的处理动作act和oact指向sigaction结构体sigaction结构体structsigaction{void(*sa_handler)(int);void(*sa_sigaction)(int,siginfo_t*,void*);sigset_tsa_mask;intsa_flags;void(*sa_restorer)(void);};将sa_handler赋值为常数SIG_IGN传给sigaction表示忽略信号赋值为常数SIG_DFL表示执行系统默认动作赋值为一个函数指针表示用自定义函数捕捉信号或者说向内核注册了一个信号处理函数该函数返回值为void可以带一个int参数通过参数可以得知当前信号的编号这样就可以用同一个函数处理多种信号显然这也是一个回调函数不是被main函数调用而是被系统所调用注意当某个信号的处理函数被调用时内核自动将当前信号加入进程的信号屏蔽字当信号处理函数返回时自动恢复原来的信号屏蔽字这样就保证了在处理某个信号时如果这种信号再次产生那么它会被阻塞到当前处理结束为止如果在调用信号处理函数时除了当前信号被自动屏蔽之外还希望自动屏蔽另外一些信号则用sa_mask字段说明这些需要额外屏蔽的信号当信号处理函数返回时自动恢复原来的信号屏蔽字sa_flags字段包含一些选项本章的代码都把sa_flags设为0sa_sigaction是实时信号的处理函数本章不详细解释这两个字段4.3 穿插话题——操作系统是怎么运行的4.3.1 硬件中断中断向量表就是操作系统的一部分启动就加载到内存中了通过外部硬件中断操作系统就不需要对外设进行任何周期性的检测或者轮询由外部设备触发的中断系统运行流程叫做硬件中断// Linux内核0.11源码voidtrap_init(void){inti;set_trap_gate(0,divide_error);// 设置除操作出错的中断向量值。以下雷同。set_trap_gate(1,debug);set
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进