SIGUSR1 使用者自定義訊號 預設處理:程式終止
SIGUSR2 使用者自定義訊號 預設處理:程式終止
當一個程式呼叫fork時,因為子程式在開始時複製父程式的儲存映像,訊號捕捉函式的地址在子程式中是有意義的,所以子程式繼承父程式的訊號處理方式。
但是當子程式呼叫exec後,因為exec執行新的程式後會覆蓋從父程式繼承來的儲存映像,那麼訊號捕捉函式在新程式中已無意義,所以exec會將原先設定為要捕捉的訊號都更改為預設動作。
C++父子程式使用SIGUSR1和SIGUSR2進行通訊
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
void handler(int signo)
{
switch(signo) {
case SIGUSR1: //處理訊號 SIGUSR1
printf("Parent : catch SIGUSR1\n");
break;
case SIGUSR2: //處理訊號 SIGUSR2
printf("Child : catch SIGUSR2\n");
break;
default: //本例不支援
printf("Should not be here\n");
break;
}
}
int main(void)
{
pid_t ppid, cpid;
//為兩個訊號設定訊號處理函式
if(signal(SIGUSR1, handler) == SIG_ERR)
{ //設定出錯
perror("Can't set handler for SIGUSR1\n");
exit(1);
}
if(signal(SIGUSR2, handler) == SIG_ERR)
{ //設定出錯
perror("Can't set handler for SIGUSR2\n");
exit(1);
}
ppid = getpid();//得到父程式ID
if((cpid = fork()) < 0)
{
perror("fail to fork\n");
exit(1);
}
else if(cpid == 0)
{
// 子程式內向父程式傳送訊號SIGUSER1
if(kill(ppid, SIGUSR1) == -1)
{
perror("fail to send signal\n");
exit(1);
}
while(1);//死迴圈,等待父程式的訊號
}
else
{
sleep(1);//休眠,保證子程式先執行,並且傳送SIGUSR1訊號
// 父程式向自己傳送SIGUSER2訊號
if(kill(cpid, SIGUSR2) == -1)
{
perror("fail to send signal\n");
exit(1);
}
// 必須sleep一下,否則子程式捕獲不到SIGUSER2訊號
sleep(1);
printf("will kill child\n");//輸出提示
if(kill(cpid, SIGKILL) == -1)
{ //傳送SIGKILL訊號,殺死子程式
perror("fail to send signal\n");
exit(1);
}
if(wait(NULL) ==-1)
{ //回收子程式狀態,避免殭屍程式
perror("fail to wait\n");
exit(1);
}
printf("child has been killed.\n");
}
return;
}
捕捉SIGUSR1和SIGUSR2的簡單程式
#include <stdio.h> #include <signal.h> #include <unistd.h> static void sig_usr(int); int main(void) { if(signal(SIGUSR1, sig_usr) == SIG_ERR) printf("can not catch SIGUSR1\n"); if(signal(SIGUSR2, sig_usr) == SIG_ERR) printf("can not catch SIGUSR2\n"); for(;;) pause(); } static void sig_usr(int signo) { if(signo == SIGUSR1) printf("received SIGUSR1\n"); else if(signo == SIGUSR2) printf("received SIGUSR2\n"); else printf("received signal %d\n", signo); }
執行結果:
[chinsung@thinkpad apue]$ ./a.out &
[1] 2581
[chinsung@thinkpad apue]$ kill -USR1 2581
received SIGUSR1
[chinsung@thinkpad apue]$ kill -USR2 2581
received SIGUSR2
[chinsung@thinkpad apue]$ kill 2581
[1]+ Terminated ./a.out