- 概述
- 信號機制的兩個常用函數
signal
#include <signal.h> void (*signal(int signo, void (*func)(int)))(int);
返回值:若成功則返回信號以前的處理配置,如果出差則返回SIG_ERR;
或者用如下的定義:
typedef void (*sighandler_t)(int); sighandler_t signal(int signo, sighandler_t handler);
這個函數的功能是捕捉到相應的信號(signo),並用相應的處理函數(func/handler)來對信號進行相應的相應,是會替代原來的處理函數。但是要和足以,SIGKILL和SIGSTOP這兩個信號是既不能被捕捉也不能被忽略的!(當時我們做一個后台程序,我還想用捕捉SIGKILL的方式來免殺呢)。
KILL
#include<signal.h> int kill(pid_t pid, int sig);
這個函數的功能是將信號發送給進程或者進程組。
pid > 0 :要發送信號的進程號
pid = 0 :信號被發送到所以和當前進程在同一個進程組的進程
pid = -1 : 信號發送給發送進程有權限向他們發送信號的系統上的所以進程
pid < -1 :信號發送給其進程組ID等於pid的絕對值
- 幾個比較常用的信號
SIGIGN:忽略改信號
SIGDEF:采用系統默認方式處理信號
SIGCHLD:在一個進程終止或者停止時,將該信號發送給其父進程,父進程的wait函數通常用來捕捉這個信號
SIGINT:當用戶按中斷鍵(delete/ctrl+c)時將產生這個信號
SIGKILL:此信號可以用於殺死一個進程
SIGSTOP:這是個作業控制信號,用於停止一個進程 這個信號和SIGKILL是僅有的兩個不能被捕獲或忽略的信號
SYSUSR1/2:用戶定義的信號,用於應用程序
- 程序演示
/************************************************************************* > File Name: signal.c > Author: he xingjie > Mail: gxmshxj@163.com > Created Time: Fri 25 Oct 2013 07:53:56 AM PDT ************************************************************************/ #include<stdio.h> #include<stdlib.h> #include<signal.h> void my_func(int sig_no){ if(sig_no == SIGUSR1) printf("Receive SIGUSR1.\n"); if(sig_no == SIGUSR2) printf("Receive SIGUSR2.\n"); if(sig_no == SIGINT) printf("Receive SIGINT.\n"); } int main(void) { if(signal(SIGUSR1, my_func) == SIG_ERR) printf("can't catch SIGUSR1.\n'"); if(signal(SIGUSR2, my_func) == SIG_ERR) printf("can't catch SIGUSR2.\n'"); if(signal(SIGINT, my_func) == SIG_ERR) printf("can't catch SIGINT.\n'"); kill(getpid(),SIGINT); while(1); return 0; }
當運行這個程序的時候,我們將會看到:Receive SIGINT. 然后程序不斷在循環,如果我們按ctrl+c,將會輸出:Receive SIGINT.
如果我們把程序放在后天運行,並且用 kill -USR1 pid。pid為那個進程的id,我們還將會看到Receive SIGUSR1.
- 參考資料
[1] UNIX環境高級編程
[2] 我們老師上課的課件