前言
linux下能够通过信号机制来实现程序的软中断,是一个很实用的编程方法。
我们平时在程序执行的时候按下ctrl-c、ctrl-z或者kill一个进程的时候事实上都等效于向这个进程发送了一个特定信号,当进程捕获到信号后,进程会被中断并马上跳转到信号处理函数。
默认情况下一个程序对ctrl-c发出的信号(SIGINT)的处理方式是退出进程。所以当我们按下ctrl-c的时候就能够终止一个进程的执行。
signal函数
可是有时候我们希望我们的程序在被信号终止之前运行一些特定的收尾流程。或者我们希望我们的程序在收到特定信号后可以运行我们自定义的中断操作。在linux下我们可以通过signal函数实现上述的功能。
比如:在Linux以下写一个程序。假设程序中出现死循环的话,我们就应该在键盘上按Ctrl+C来终止我们的程序,那么我们也能够捕获这个信号,然后运行我们自己的信号处理程序,输出一些实用的信息来帮助我们调试程序,这也算是一种技巧吧。假设我们不去捕获这个信号的话。那么信号产生后就去运行OS的信号处理程序。信号和中断非常像。我们既能够使用OS的中断处理程序。也能够截获中断运行自己的中断处理程序。以下是一个多线程的样例:
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <sys/wait.h> #include <sys/types.h> #define true 1 void * One(void * no) { while (true) { printf("NUAACS1\n"); sleep(1); } } void * Two(void * no) { while (true) { printf("NUAACS2\n"); sleep(1); } } void Stop(int signo) { printf("oops! stop!!!\n"); _exit(0); } int main() { int res; pthread_t A, B; signal(SIGINT, Stop); res = pthread_create(&A, NULL, One, NULL); res = pthread_create(&B, NULL, Two, NULL); res = pthread_join(A, NULL); res = pthread_join(B, NULL); return 0; }
以上是网上的资料,但另一点要注意的是,程序被中断并运行完中断函数后,也就是在中断函数中返回。那么程序会又一次返回到中断前的位置继续运行之前的程序。信号处理函数仅仅能返回void,不能返回指定的參数。
另外,对于有些函数。程序的中断可能会打断这些函数的正常运行。比方说对于sleep函数,假设一个程序再sleep的途中被中断那么该程序会立马结束sleep。