对这类情况的思考
这类情况导致的进程异常退出,并不是软件编程错误所导致,而是进程外部的异步信号所致。但是我们可以在代码编写中做的更好,通过调用signal函数绑定信号处理程序来应对信号的到来,以提高软件的健壮性。
signal函数的原型:
#include <signal.h> void (*signal(int sig, void (*func)(int)))(int); |
signal函数将信号sig和自定义信号处理程序绑定,即当进程收到信号sig时自定义函数func被调用。如果我们希望软件在运行时屏蔽某个信号,插入下面的代码,以达到屏蔽信号 SIGINT的效果:
(void)signal(SIGINT, SIG_IGN); |
执行这一行代码后,当进程收到信号SIGINT后,进程就不会异常退出,而是会忽视这个信号继续运行。
更重要的场景是,进程在运行过程中可能会创建一些临时文件,我们希望进程在清理这些文件后再退出,避免遗留垃圾文件,这种情况下我们也可以调用signal函数实现,自定义一个信号处理程序来清理临时文件,当外部发送信号要求进程终止运行时,这个自定义信号处理程序被调用做清理工作。代码清单2是具体实现。
清单2.调用signal函数绑定自定义信号处理程序
|
第二类:编程错误导致进程运行时异常退出
相比于第一类情况,第二类情况在软件开发过程中是常客,是编程错误,进程运行过程中非法操作引起的。
操作系统和计算机硬件为应用程序的运行提供了硬件平台和软件支持,为应用程序提供了平台虚拟化,使进程运行在自己的进程空间。在进程看来,它自身独占整台系统,任何其它进程都无法干预,也无法进入它的进程空间。
但是操作系统和计算机硬件又约束每个进程的行为,使进程运行在用户态空间,控制权限,确保进程不会破坏系统资源,不会干涉进入其它进程的空间,确保进程合法访问内存。当进程尝试突破禁区做非法操作时,系统会立刻觉察,并且终止进程运行。
所以,第二类情况导致的进程异常退出,起源于进程自身的编程错误,错误的编码执行非法操作,操作系统和硬件制止它的非法操作,并且让进程异常退出。
在实现上,操作系统和计算机硬件通过异常和异常处理函数来阻止进程做非法操作。