天天看點

linux之sigaction函數的簡單使用

1.sigaction函數

原型:int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

參數:

                act:傳入參數,新的處理方式。

                oldact:傳出參數,舊的處理方式。

作用:修改信号處理動作(通常在 Linux 用其來注冊一個信号的捕捉函數)

傳回值:成功:0;失敗:-1,設定 errno

struct sigaction 結構體

struct sigaction {
    void (*sa_handler)(int);
    void (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t sa_mask;
    int sa_flags;
    void (*sa_restorer)(void);
};
           

重點掌握:

(1)sa_handler:指定信号捕捉後的處理函數名(即注冊函數)。也可指派為 SIG_IGN 表忽略 或 SIG_DFL 表執行預設動作

(2)sa_mask: 調用信号處理函數時,所要屏蔽的信号集合(信号屏蔽字)。注意:僅在處理函數被調用期間屏蔽生效,是臨時性設定。

(3)sa_flags:通常設定為 0,表使用預設屬性。

2.信号捕捉特性

        (1)程序正常運作時,預設 PCB 中有一個信号屏蔽字,假定為☆,它決定了程序自動屏蔽哪些信号。當注冊了某個信号捕捉函數,捕捉到該信号以後,要調用該函數。而該函數有可能執行很長時間,在這期間所屏蔽的信号不由☆來指定。而是用 sa_mask 來指定。調用完信号處理函數,再恢複為☆。

        (2)XXX 信号捕捉函數執行期間,XXX 信号自動被屏蔽。

        (3)阻塞的正常信号不支援排隊,産生多次隻記錄一次。(後 32 個實時信号支援排隊)

3.代碼: test_sigac.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>

//本程式要實作:在使用sigaction函數捕捉信号SIGINT,在執行信号捕捉後的處理函數時,屏蔽信号SIGQUIT。
//測試:執行程式後,ctrl + c後,輸出 2 signal is catched 
//此時 ctrl + \ 後,程序并沒有退出。需要重開終端,手動殺死該程序
void docatch(int signo)
{
	printf("%d signal is catched\n",signo);
	while(1);
}

int main()
{
	int ret;
	struct sigaction act;
	
	act.sa_handler = docatch;			//指定信号捕捉後的處理函數名(注冊函數)
	//act.sa_mask是調用信号處理函數時,所要屏蔽的信号集合(信号屏蔽字)
	sigemptyset(&act.sa_mask);			//将信号集act.sa_mask清0
	sigaddset(&act.sa_mask,SIGQUIT);	//添加信号SIGQUIT到集合act.sa_mask中
	act.sa_flags = 0;					//預設屬性,信号捕捉函數執行期間,自動屏蔽本信号
	
	ret = sigaction(SIGINT,&act,NULL);//捕捉SIGINT信号
	if(ret < 0){
		perror("sigaction error");
		exit(1);
	}
	
	while(1);

	return 0;
}
           

結果:

linux之sigaction函數的簡單使用

繼續閱讀