您的位置:首页 > 运维架构 > Linux

Linux内核的信号机制——怪胎

2015-12-01 23:12 330 查看
信号机制是Unix的一大特色,因为是特色,所以很多同学在编程时,有些不能理解(超出理解范围?)。

本文对Linux信号机制做一个分析。

常见signal使用如下:

void mysig(){

printf("got a sig!\n");

}

int main() { 
printf("process id is %d !\n",getpid()); 
signal(SIGINT, mysig); 
for (;;) ; 


当我们在控制台按Ctrl + C时,控制台会打印出"got a sig!"。

这个过程到底发生了什么?

如果你没有深入思考过操作系统的工作原理,就算是写过几年的C程序,也是一头雾水。

如果是初学C,都知道,C程序是从main函数开始,跑到最后一行,顺序执行!signal的概念完全就是个怪胎!

signal的内核操作过程如下:

1,signal()系统调用,发生0x80中断(陷阱),调用sys_signal()。

2,sys_signal()获取到传入的信号编号(SIGINT等宏定义),以及对应的handler,把它注册到current宏的sigaction[signum-1],current宏指向了正在执行的task_struct,而sigaction是task_struct的一个成员。

3,中断服务程序执行完毕之后,准备返回用户程序,返回之前,检查当前进程可以处理的信号——此时,信号可能(一般)还没发生。

4,程序员按了Ctrl +C,内核接收到这个信号了,对应的sigaction的选项被标记。

5,内核又发生了中断,返回用户程序前,检查可以处理的信号,发现有信号可以处理,do_signal(),跳转到注册的handler(),程序员感觉到穿越了(也就是最难理解的地方)

6,handler()执行完毕之后,执行特殊系统调用,返回内核态。

7,从内核态返回用户模式,出栈,恢复到中断发生之前,接着执行之前的代码。

所以,关键还是对中断的理解——理解了中断,linux内核就理解了三分之一!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: