展会信息港展会大全

从kernel源代码的角度分析signal的错误用法和注意事项(zt)
来源:互联网   发布日期:2011-09-28 17:35:13   浏览:8423次  

导读:从kernel源代码的角度分析signal的错误用法和注意事项(zt) - 技术文档 - 系统管理 系统管理 Linux 技术文档...


!声明: 按照Linux的习惯, 我的这篇文档也遵循GPL 协议: 你可以随意应用并修改本文档,必须发布你的修改,使其他人可以获得一份Copy,尤其是给我一份Copy! 我的mail :
bob_zhang2004@163.com
|
zhanglinbao@gmail.com
均可。欢迎论坛转载! 目前有些内容已经在
www.linuxforum.net
中进行过讨论,可以前往:
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=linuxK&Number=607800&page=0&view=&sb=&o=&fpart=&vc=1
   和  
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=linuxK&Number=607228&page=1&view=collapsed&sb=5&o=7&fpart
=   欢迎大家继续讨论,以便文档更加完善! 多谢!周末愉快!                                 
--bob
读这份文档之前,建议先浏览一下 《Unix Advanced Programming》里面的signal一章和下面这份出自IBM论坛的文章:进程间通信 信号(上)
http://www-128.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html
  ,和 进程间通信 信号(下)
http://www-128.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html
该作者写了一个系列的进程间通信的文章, 我只是希望对该篇作个补充!
因为它们都没有从源代码的角度分析,所以我尝试了一下把上层应用与kernel实现代码分析结合起来,这样使用者才可能真正的理解signal的用法和原理!
目前介绍signal理论和用法书不少,缺点是只介绍其用法,非常深奥拗口,不容易理解;  而介绍kernel源代码的书,侧重于代码分析,不讲实际应用!
我就想到如果把两者结合起来,对上层使用signal函数的用户必然能知起所以然了,而且只要顺着我的代码注释大概粗读一下源码就可以理解 signal的特性和用法以及你碰到的种种疑惑和不解了。
如果你对signal的特性和用法有什么疑惑的话, 如果对kernel也感兴趣的话, 就可以继续读源码 , 把这篇文章加以补充和完善!  前提是遵守上面的声明!

因为工作的需要,用了2天的时间详细的读了一下 linux kernel 2.4.24 版本的signal方面的源代码,收获不小, 因为以前发现看>的时候 ,不知道是大师的话太深奥,还是中文版太烂,有的东西就是理解不了,象吃满头嗫住了,很是不爽,总觉得心里不踏实。看看源码才真正明白什么是信号,以及它的kernel流程,所以建议大家对某个系统调用,函数什么的,如果存在疑惑和不理解的,强烈建议读读源码,粗读也非常不错,关键要由参考书领着读,比如> 就非常不错。
有的时候看着一个系统调用成堆的手册页,还真不如看看它的实现来得更快, 当然两下对照着看就快了。   
另外提醒大家 > 可不是 《Linux Advanced Programming》啊!尽信书不如无书 ......
在此通过阅读源码,弄清楚了5个问题,每个问题我都给出了结论,当然这些结论肯定是正确的,至少《Unix Advanced Programming》是这样认为的, 我只是从kernel的角度是验证它的正确性(简单的写了几个测试程序,以验证kernel的做法),而且也归纳了 一些结论,比如如何避免 Zobie进程 等。  相信对大家会有价值,也可以mail讨论!或者上相应的论坛!
首先总结一下:在PC linux(RHT 9.0 + kernel-2.4.24) 键盘产生的信号:
Ctrl + c     SIGINT(2) terminate ,以前我总想当然以为是 SIGTERM(15)!
Ctrl + \ SIGQUIT(3) terminate
Ctrl + z SIGTSTP(20) 挂起进程
对于一般应用:
挂起一个进程: kill(pid, SIGSTOP)   或 kill(pid,SIGTSTP) , 或 SIGTTIN , SIGTTOU 信号
恢复一个进程  kill(pid,SIGCONT);  
杀死所有的符合某个名字的进程 :比如killall  curl ,发送的是SIGTERM 信号
强制杀死某个进程 kill –9 curl  ,发送的是SIGKILL 信号, 在kernel中,SIGKILL和SIGSTOP是不能被忽略的
....
剩下的大家都清楚了,这里就不罗嗦了。
子进程结束时候发给父进程的信号:   SIGCHLD ,这个比较特殊 , 且看下面3>的论述
Agenda :
1>不可靠的信号
2>Zombie进程(僵尸进程)与signal
3>特殊的SIGCHLD 信号
4>信号与进程的关系 ,进程的要求
5>pause() 与 signal
6>关于信号的技巧
1> 不可靠的信号(linux继承Unix的结果,考虑兼容性) ,  和可靠的信号(主要就是信号可以排队处理,信号不丢失,linux自己的,但大家好像用的不多)
什么是不可靠的信号:简单的说,就是当你向一个进程发送 singal( 1~31,注意这里讨论是 1~31 )的时候 , 当进程还没有处理该信号(这时候叫pending,未决信号)或者是正在调用信号处理函数的时候,  进程又收到了一个同样的信号 , kernel会把第二个信号丢弃,或者叫和一个信号合并,这样的信号就是 不可靠的信号  ,具体正方面的比较权威的解释请参考
http://www-128.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html
,这篇文章对于信号理论介绍的非常详细清楚明白, 个人认为比《Unix advanced Programming》要更好!
系统实现是这样的:
==>  kernel/signal.c  
int send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
{
.............................................
/*  
  如果当前进程的未决信号集中已经包括了这个信号,就不重新注册后来现在的同样的信号了,  
  据个例子:  给进程发了 SIGTERM 信号 , 但是kernel还没有来得及处理(进程只有在kernel空间即将返回道用户空间的时候,
  kernel才会检测pending信号 ,然后才会调用do_signal()函数去处理)
  这个时候又发了一个SIGTERM,那么第二个SIGTERM 肯定要被cut掉了。
*/
if (sig pending.signal, sig))  //SIGRTMIN 是分水岭 , 小于它的都是不可靠的信号,否则就是实时信号
  goto out;  //跳出了正常执行的范围
....................................................
}
!正确的: 1~31都是不可靠的信号! SIGRTMIN ~SIGRTMAX都是可靠的信号!
以前大家有个误区:
!误区1>
以为不可靠的信号,是指 给进程发了一个信号(之前没有发过),那么这个信号可能丢失,也就是进程收不到
这样的理解是错误的, 根据上面的定义 , 应该是”一个信号发了多遍,后来的信号丢失了, 而不是第一个丢了“。
具体的原因可以参照上面的代码分析,就一目了然,还可以看 《unix advanced programming 》,不过我觉得它讲的都是老的Unix ,对Linux只能是参考而已!
!误区2>
signal() 发送的是不可靠的信号 ,而 sigaction()发送的是可靠的信号


只要是1-31的信号,它就是不可靠的信号。 无论在注册信号处理函数的时候用的是sigaction() ,还是signal() ,只要你发送的信号 是  1-31,那么就是不可靠的信号。中国有句俗语叫”烂泥扶不上墙“,我看放在这里挺合适!
signal()和 sigaction()的差别到底在哪里呢?   通过对比一看便知:
   对于signal() ,它的kernel实现函数,也叫系统调用服务历程sys_signal()
==>kernel/signal.c
asmlinkage unsigned long
sys_signal(int sig, __sighandler_t handler)
{
struct k_sigaction new_sa, old_sa;
int ret;
new_sa.sa.sa_handler = handler;
ne

赞助本站

人工智能实验室
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港