Linux的SIGUSR1和SIGUSR2訊號

小 樓 一 夜 聽 春 雨發表於2018-01-16
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

  

相關文章