pause函數 pause函數掛起調用它的進程,直到有任何消息到達。 調用進程必須有能力處理送達的信號,否則信號的默認部署就會發生。 int pause(void); 只有進程捕獲到一個信號的時候pause才返回,如果遞送到的信號引發了對信號的處理,那么處理工作將在pause返回前執行。 pause總是返回-1,並且將變量errno設置為EINTR。
發送信號和捕獲信號是相輔相成的。
每個進程能夠決定響應除了SIGSTOP和SIGKILL之外的其他所有信號。 SIGSTOP和SIGKILL不能被捕獲或者忽略。
捕獲信號不是真的去捕獲它,而是等待信號被發送過來。
當執行一個程序的時候,所有信號的狀態都是系統默認或者忽略。
當一個進程調用fork的時候,其子進程繼承父進程的信號處理方式,所以信號捕捉函數的地址在子進程中是有意義的,
定義信號處理器
某些情況下,一個信號的默認動作就是所希望的行為。但更多場合下,你可以改變默認行為或者執行額外的代碼。
如果想改變默認行為就必須定義並安裝一個自動的信號處理器。
指向函數的指針 --可以用指針變量指向整型變量、字符串、數組、結構體、也可以指向一個函數。 --一個函數在編譯時被分配一個入口地址,這個入口地址被稱為函數指針。 --可以用一個指針變量指向函數,然后通過該指針變量調用此函數。
回調函數 --回調函數就是一個通過函數指針調用的函數。 --如果把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。 --回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外一方調用,用於對該事件或條件進行響應。 --windows編程下的窗口過程就是典型的回調函數。
signal函數 --UNIX/Linux處理信號最常用的接口是signal函數 .在命令行使用kill命令,向指定進程發送信號。 --使用kill函數 typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); signal函數一般用於捕捉信號,其功能是為一個信號注冊一個回調函數。 第一個參數signum一般就是系統提供的信號,表示要捕捉這個信號。 第二個參數指定類型的函數指針(typedef void (*FUNC)(int)),該函數有個int型參數,int代表捕獲到的信號值。 捕捉多個信號需要使用多個signal()函數 進程捕捉到信號並對信號進行處理時,進程正在執行的指令序列就被信號處理程序臨時中斷。它首先執行該信號處理程序中的指令。 如果信號處理程序返回(沒有調用exit(0)或者abort()),則繼續執行在捕獲到信號時進程正在執行的正常指令序列。 在信號處理程序中,不能判斷捕捉到信號是進程正在何處執行。 編譯后執行該程序 用kill命令發送信號給該程序 --kill命令作用其實不是‘殺死’的意思,而是將指定信號發送給指定進程。 --kill [-s signal|-p] [--] pid... --kill可以用-s指定具體的信號發給指定的進程。 --kill -s 2 2365 (SIGINT的值就是2,這個命令是將SIGINT信號發送給指定進程) --信號都是整數
//捕捉信號 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <signal.h> void catch_signal(int sign) { switch(sign) { case SIGINT: printf("SIGINT signal\n"); exit(0); break; case SIGALRM: printf("SIGALRM signal\n"); break; } } int main(int arg, char *args[]) { signal(SIGINT,catch_signal); signal(SIGALRM,catch_signal); int i=0; while(1) { printf("hello god %d\n",i++); sleep(1); } return 0; }
.SUFFIXES:.c .o CC=gcc SRCS=hello.c OBJS=$(SRCS:.c=.o) EXEC=tec start:$(OBJS) $(CC) -o $(EXEC) $(OBJS) @echo "^_^----OK----^_^" .c.o: $(CC) -Wall -g -o $@ -c $< clean: rm -f $(OBJS) rm -f $(EXEC)