本篇文章主要學習linux的訊號處理機制,著重學習遮蔽訊號部分。遮蔽訊號處理的兩種方式類似於訊號的捕獲,一種方式是直接對其設定,另一種方式是先獲得描述符的掩碼,然後對其設定操作。在linux系統中,如何處理某個程序傳送的乙個特定訊號呢?一般來說有三種方式:本文主要參考自《嵌入式linux系統使用開發》,作者何永琪,thanks.
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是不能被阻塞的...