48-信号大结局

来源:互联网 发布:张恩民 php 编辑:程序博客网 时间:2024/06/10 15:08

信号这个专题花了太长的篇幅,也可能是目前你学的最累的一次,实验也非常多。这篇文章就帮我们理一理整个信号的脉络。


信号专题总结

从理解进程能够接收信号开始,就探讨了进程对信号做出的默认动作。接下来我们开始引入ANSI C提供的 signal 信号注册函数,帮助我们自己处理信号。

掌握了信号处理函数,你就可以使用异步的方式处理子进程先行退出的情况了(SIGCHLD)。同时我们演示了信号的不可靠性,意思是说如果同时有很多相同的信号到来,会自动合并成一个交给信号处理函数处理。

接下来,又简单的介绍了一下编写信号处理函数需要注意的事项——信号处理函数必须是可重入的!并列举了 getpwnam 这个例子,如果不记得了,可以翻过去再看看。

逐渐熟练的掌握了信号处理函数的种种细节后,探讨了信号发送函数 kill 和 alarm,希望同学们能够分清楚这两个函数在发送信号上的差异。

在一步一步踩踏实后,为了给阻塞信号未决信号做铺垫,不得不提前为信号集做铺垫。但是为了防止过于突兀,一开始并未提及信号集的概念,标题取了个《装信号的容器 sigset》,其实是希望大家能够接收,在掌握了对容器的 5 种操作方法(回忆)后,就有基础去理解阻塞信号了。

讲解阻塞信号集的时候,提到进程 PCB 中其实有两个装信号的容器,分别是阻塞信号集和未决信号集,大家需要理解这两信号集的含义和作用。

基本上到这里,关于信号的基础大家相对来说已经完成了70%了。后面就是关于信号更高级的部分,为了能够更精细的控制信号处理函数和信号的行为,引入了 POSIX 标准提供的信号注册函数 sigaction。实际上 signal 函数的底层就是用 sigaction 实现的。

需要注意的是 sigaction 的第二个参数,它是一个结构体,每个成员需要大家都能够熟练理解掌握。特别是成员 sa_flags,它的选项用来控制信号处理函数的和信号的行为。比如什么时候带参数?什么时候让被打断的系统调用重启等等。

为了能讲清楚被中断的系统调用自动重启,我们深入到了内核,去理解信号处理函数的执行期,有了这些内功后,再去理解系统调用自动重启这件事就不难了。

在信号收尾的时候,本来是不打算讲解 siglongjmp 的,但是问了一些同学后,他们说有必要讲讲。所以在信号结尾的时候,讲了有关在信号处理函数中做 longjmp 行为可能会带来的 bug。

为了能够更好的理解 siglongjmp 函数的行为,还得从两个更基础的函数 setjmp 和 longjmp 讲起,对比它们与 goto 跳转的区别。

如果只讲行为,并没什么高大上的东西,后面就着重分析了函数调用原理,什么是函数栈帧,以满足有些同学的好奇心,最后还实现了一个属于自己的 longjmp 函数。

最后一篇,讲解了信号处理函数的临时阻塞特性,使用 longjmp 函数的危险性。所以如果要在信号处理函数里做非局部性转移,应该使用 siglongjmp。


理清了整个脉络了,学习起来,就会轻松很多。其中很多知识点都是环环相扣的,缺一不可。

从下一篇开始,探讨进程间通信!

0 0
原创粉丝点击