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内核就理解了三分之一!
本文对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内核就理解了三分之一!
相关文章推荐
- Linux下配置文件读取操作流程及其C代码实现
- 我的VPS选择之路
- linux命令复用技巧
- Linux学习笔记(3)之文件操作
- Linux负载均衡软件之LVS
- linux下如何设置vip(虚拟ip)
- Linux下select&poll&epoll的实现原理(一)
- linux软件包管理
- linux命令编辑技巧
- RHEL6忘记root密码的解决办法
- CentOS排错
- Linux系统忘了root密码
- linux察看安装包有那些
- Linux tee命令
- linux下自己安装软件添加快捷方式
- 多线程
- 【Linux程序设计】之进程控制&守护进程
- linux远程访问
- centos启动流程[转]
- Linux作业控制