前言
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。