Linux中如何遮蔽訊號

2021-08-11 02:20:18 字數 2653 閱讀 7233

本篇文章主要學習linux的訊號處理機制,著重學習遮蔽訊號部分。遮蔽訊號處理的兩種方式類似於訊號的捕獲,一種方式是直接對其設定,另一種方式是先獲得描述符的掩碼,然後對其設定操作。

本文主要參考自《嵌入式linux系統使用開發》,作者何永琪,thanks.

在linux系統中,如何處理某個程序傳送的乙個特定訊號呢?一般來說有三種方式:

1) 忽略訊號

2) 遮蔽訊號

3) 為該訊號新增使用者自定義的訊號處理函式,從而優先呼叫,而不使用預設的操作。

#include 

int sigemptyset(sigset_t *set);

int sigfillset(sigset_t *set);

int sigaddset(sigset_t *set,int signum);

int sigdelset(sigset_t *set,int signum);

int sigismember(const sigset_t *set,int signum);

其中set引數指向要操作的訊號集,而signum引數則代表乙個指定的訊號,各個函式的作用如下:

函式作用

sigemptyset

清空訊號集,返回0表示成功,-1表示失敗

sigfillset

將所有訊號加入訊號集,返回0表示成功,-1表示失敗

sigaddset

將指定訊號加入訊號集,返回0表示成功,-1表示失敗

sigdelset

將指定訊號從訊號集中去除,返回0表示成功,-1表示失敗

sigismember

判斷乙個指定的訊號是否在訊號集中,返回1表示在訊號集中,0表示不在訊號集中,-1表示有錯誤發生。

有了這些函式,程式設計時就沒必要直接對sigset_t型資料進行操作了,從而也不必知道它的具體含義。一般來說,訊號集在使用前需要先用sigemptyset或者sigfillset函式進行初始化,然後呼叫sigaddset或sigdelset函式增加或去除需要的訊號。

在呼叫sigaction函式時,可以設定訊號處理時需要遮蔽的訊號。實際上在**中也可以直接設定或獲取程序的訊號掩碼。所使用的介面函式如下:

int sigprocmask(int how,const sigset_t *set, sigset_t *oldset);
其各個引數及返回值含**釋如下:

引數作用

how指定操作訊號掩碼的方式

set指向用於設定訊號掩碼的訊號集

oldset

用於返回原來的訊號掩碼

返回值0表示成功,-1表示失敗

sigprocmask函式根據引數how指定的方式,設定當前程序的訊號掩碼,並把原來的訊號掩碼儲存在引數oldset指向的訊號集中返回。

如果set引數為null,則不修改訊號掩碼;如果oldset引數為null,則不返回原來的訊號掩碼。

這裡關鍵要理解引數how的使用。它由如下三個取值:

引數how

作用sig_block

將set引數指向的訊號集中的訊號加入到訊號掩碼中

sig_unblock

將set引數指向的訊號集中的訊號從訊號掩碼中刪除

sig_setmask

將set引數指向的訊號集中的訊號設定為訊號掩碼

1)遮蔽訊號的兩種方式

因此,遮蔽某個訊號有兩種方式,,下面以siguser1為例進行說明:

第一種方式為使用sig_block操作方式,**如下:

sigset_t sigset;

sigemptyset(&sigset);

sigaddset(&sigset,siguser1);

sigprocmask(sig_block,&sigset,null);

第二種方式為使用sig_setmask操作方式,**如下:

sigset_t set;

sigprocmask(sig_setmask,null,&set); //先得到當前的訊號掩碼

sigaddset(&set,siguser1);//將要遮蔽的訊號加入

sigprocmask(sig_setmask,&set,null);

2)解除遮蔽訊號的兩種方式

同樣,要解除對訊號的遮蔽,也有兩種方式,仍以siguser1為例進行說明。

第一種方式,使用使用sig_unblock操作方式,**如下:

sigset_t sigset;

sigemptyset(&sigset);

sigaddset(&sigset,siguser1);

sigprocmask(sig_unblock,&sigset,null);

第二種方式,使用sig_setmask操作方式,**如下:

sigset_t set;

sigprocmask(sig_setmask,null,&set); //先得到當前的訊號掩碼

sigdelset(&set,siguser1);//將要遮蔽的訊號去除

sigprocmask(sig_setmask,&set,null);

linux 訊號遮蔽

include include include include include include sigemptyset newmask 獲取空遮蔽訊號集 sigfillset newmask 獲取遮蔽了所有訊號的遮蔽訊號集,除了那兩個sigkill sigstop sigpending pendma...

如何實現訊號遮蔽

linux中常見訊號量只有31個,所以程序pcb中表示常見的訊號量只用乙個位元組表示就夠了,程序得到了乙個訊號就是對應的乙個bit位由0改變為1。訊號被系統傳送給乙個程序,就是改變pcb中表示訊號量的位元組中對應的乙個bit位。程序收到某一訊號,相當於向表示訊號量的位元組中寫入了乙個訊號量。關於訊號...

linux程序中的訊號遮蔽

在linux的程序中可以接收到各種的訊號,並且如果你不對訊號進行處理,linux中的程序就會採用預設的處理方式處理,比如ctrl c的訊號,程序對它的處理就是終止程序的執行。在linux中,我們也可以在程序中遮蔽掉某些訊號,使程序不去處理這些訊號,但其中的sigkill和sigstop是不能被阻塞的...