信號列表
SIGABRT 進程停止運行 6 SIGALRM 警告鍾 SIGFPE 算述運算例外 SIGHUP 系統掛斷 SIGILL 非法指令 SIGINT 終端中斷 2 SIGKILL 停止進程(此信號不能被忽略或捕獲) SIGPIPE 向沒有讀的管道寫入數據 SIGSEGV 無效內存段訪問 SIGQOUT 終端退出 3 SIGTERM 終止 SIGUSR1 用戶定義信號1 SIGUSR2 用戶定義信號2 SIGCHLD 子進程已經停止或退出 SIGCONT 如果被停止則繼續執行 SIGSTOP 停止執行 SIGTSTP 終端停止信號 SIGTOUT 后台進程請求進行寫操作 SIGTTIN 后台進程請求進行讀操作
typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); signal函數 作用1:站在應用程序的角度,注冊一個信號處理函數 作用2:忽略信號,設置信號默認處理 信號的安裝和回復 參數 --signal是一個帶signum和handler兩個參數的函數,准備捕捉或屏蔽的信號由參數signum給出,接收到指定信號時將要調用的函數有handler給出 --handler這個函數必須有一個int類型的參數(即接收到的信號代碼),它本身的類型是void --handler也可以是下面兩個特殊值:① SIG_IGN 屏蔽該信號 ② SIG_DFL 恢復默認行為
//忽略,屏蔽信號
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <signal.h> int main(int arg, char *args[]) { pid_t pid=fork(); if(pid==-1) { printf("fork() failed! error message:%s\n",strerror(errno)); return -1; } //注冊信號,屏蔽SIGCHLD信號,子進程退出,將不會給父進程發送信號,因此也不會出現僵屍進程 signal(SIGCHLD,SIG_IGN); if(pid>0) { printf("father is runing !\n"); sleep(10); } if(pid==0) { printf("i am child!\n"); exit(0); } printf("game over!\n"); return 0; }
//恢復信號 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <signal.h> void catch_signal(int sign) { switch (sign) { case SIGINT: printf("ctrl + C 被執行了!\n"); //exit(0); break; } } int main(int arg, char *args[]) { //注冊終端中斷信號 signal(SIGINT, catch_signal); char tempc = 0; while ((tempc = getchar()) != 'a') { printf("tempc=%d\n", tempc); //sleep() } //恢復信號 signal(SIGINT, SIG_DFL); while (1) { pause(); } printf("game over!\n"); return 0; }
//signal()函數的返回值 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <signal.h> void catch_signal(int sign) { switch (sign) { case SIGINT: printf("ctrl + C 被執行了!\n"); //exit(0); break; } } int main(int arg, char *args[]) { /* * signal()函數的返回值是signal()函數上一次的行為 * */ typedef void (*sighandler_t)(int); //因為第一次注冊信號SIGINT,所以上一次的行為就是默認行為 sighandler_t old=signal(SIGINT, catch_signal); if(old==SIG_ERR) { //注冊信號失敗 perror("signal error"); } /*正規寫法*/ if(signal(SIGQUIT,catch_signal)==SIG_ERR) { //注冊新號失敗 perror("signal error"); } char tempc = 0; while ((tempc = getchar()) != 'a') { printf("tempc=%d\n", tempc); //sleep() } //把默認行為重新注冊,不就是恢復默認信號了 signal(SIGINT, old); while (1) { pause(); } printf("game over!\n"); return 0; }