Linux訊號集相關函式操作

2021-06-03 01:55:26 字數 3229 閱讀 8681

在linux的程序中可以接收到各種的訊號,並且如果你不對訊號進行處理,linux中的程序就會採用預設的處理方式處理,比如ctrl-c的訊號,程序對它的處理就是終止程序的執行。

在linux中,我們也可以在程序中遮蔽掉某些訊號,使程序不去處理這些訊號,但其中的sigkill和sigstop是不能被阻塞的。

在這裡先介紹幾個訊號的函式:

int sigempty(sigset_t *set);                 // 清空訊號集set

int sigfillset(sigset_t *set);                   // 填滿訊號集,即讓set包含所有的訊號

int sigaddset(sigset_t *set, int signo);  // 在set中增加signo訊號

int sigdelset(sigset_t *set, int signo);   // 在set中去掉signo訊號

int sigismember(sigset_t *set, int signo); // 訊號signo是否在訊號集set中

int sigprocmask(int how, const sigset_t set, sigset_t oset); // 若oset非空,則程序的當前訊號遮蔽字通過oset返回,若set是乙個非空指標,著引數how指示如何修改當前訊號的遮蔽字,how可以取三個值:

sig_block:增加乙個訊號。

sig_unblock:解除乙個訊號。

sig_setmask:該程序的訊號將被set訊號集取代。

int sigpengding(sigset_t *set);  // 該函式返回訊號集,該訊號通過set引數返回。

以上函式都在#include 標頭檔案中。

下面用《unix環境高階程式設計》裡的乙個例子說明一下,**有所修改,先看**(main.c,裡面有個人對**的注釋):

view plain

copy to clipboard

print?

#include 

#include 

#include 

static

void

sig_quit(int);  

intmain(void)  

//設定乙個空的訊號集

sigemptyset(&newmask);  

sigaddset(&newmask, sigquit); // 在這個訊號集中增加sigquit訊號

//在當前程序中增加newmask訊號集作為遮蔽訊號集,oldmask返回當前程序的訊號集

if (sigprocmask(sig_block, &newmask, &oldmask) < 0)   

sleep(5);  

//返回當前程序訊號集

if (sigpending(&pendingmask) < 0)  

//檢查sigquit訊號是否在當前訊號集中

if (sigismember(&pendingmask, sigquit))  

printf("/nsigquit pending/n");  

//恢復程序的訊號集

if (sigprocmask(sig_setmask, &oldmask, null) < 0)  

printf("sigquit unblocked/n");  

sleep(5);  

exit(0);  

}  static

void

sig_quit(int signo)  

}  編譯: gcc main.c

生成:a.out

執行:./a.out

輸出如下(ubuntu9.10):

^/                          

sigquit pending    

caught sigquit      

sigquit unblocked

^/退出                   

下面解釋一下輸出:

^/                                在第一次sleep(5)的5秒中內產生訊號一次(按ctrl+/)

sigquit pending          從sleep返回後

caught sigquit           在訊號處理函式中

sigquit unblocked       從sigprocmask返回後

^/退出                          再次產生訊號

我們對著程式來看下輸出。

在我們設定sigquit遮蔽字和恢復程序的訊號集這段時間,我們產生的sigquit訊號,我們的程序並沒去處理,所以輸出了sigquit pending 。

在我們恢復程序的訊號集後,我們程序就撲捉到了我們剛才產生的訊號,因而就輸出了caught sigquit,在sig_quit函式中,我們恢復了sigquit的預設處理方式(即終止程序執行),程序當我們再次產生sigquit訊號,程序就退出了。

當我們產生程序時,一些unix系統會對程序中要處理的訊號進行排隊,我們的程序會對訊號佇列中的訊號進行處理。我們再執行一下剛才的程式,在第一次sleep(5)的5秒中內產生訊號10次訊號,看下會怎麼樣,下面是我的輸出:

^/^/^/^/^/^/^/^/^/^/     

sigquit pending                  

caught sigquit                  

sigquit unblocked               

^/退出                              

下面解釋一下輸出:

^/^/^/^/^/^/^/^/^/^/   在第一次sleep(5)的5秒中內產生訊號10次訊號

sigquit pending               從sleep返回後

caught sigquit                從sigprocmask返回後 

sigquit unblocked           從sigprocmask返回後

^/退出                              再次產生訊號

這裡可以看到linux系統對沒有對訊號進行排隊,產生10次訊號,只處理一次。

在上面的例子中,我們用signal函式來指定訊號的處理函式,用sigprocmask來指定訊號遮蔽字,其實這些都可以在乙個函式中解決,它就是sigaction,推薦使用sigaction函式。

linux 訊號集操作

訊號掩碼 被阻塞的訊號集 每個程序都有乙個用來描述哪些訊號傳送來將被阻塞的訊號集,如果某種訊號在某個程序的阻塞訊號集中,則傳送到該程序的此種訊號將會被阻塞。當前被程序阻塞的訊號集也叫訊號掩碼,型別為sigset t。每個程序都有自己的訊號掩碼,且建立子程序時,子程序會繼承父程序的訊號掩碼。訊號阻塞和...

Linux 訊號的處理以及訊號集操作函式

首先來再次看看這張圖 從上圖來看,每個訊號只有乙個bit的未決標誌,非0即1,不記錄該訊號產生了多少次,阻塞標誌也是這樣表示的。因此,未決和阻塞標誌可以用相同的資料型別sigset t來儲存,sigset t稱為訊號集,這個型別可以表示每個訊號的 有效 或 無效 狀態,在阻塞訊號集中 有效 和 無效...

訊號(六)訊號集操作函式

一 核心通過讀取未決訊號集來判斷訊號是否應該被處理。訊號遮蔽字mask可以影響未決訊號集。為我們可以在應用程式中自定義set來改變mask,來達到遮蔽指定訊號的目的。二 訊號集設定 sigset t set typedef unsigned long sigset t int sigemptyset...