標籤:訊號 signal c
前言
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 1void * 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。