首頁  >  文章  >  系統教程  >  詳解Linux訊號集操作函數

詳解Linux訊號集操作函數

WBOY
WBOY轉載
2024-02-09 15:30:31648瀏覽

讓我們先回顧一下未決訊號集是什麼。當訊號從產生到抵達目的地時,這個過程稱為訊號遞達。而訊號從產生到遞達的中間狀態,則稱為訊號的未決狀態。產生未決狀態的原因可能是訊號被阻塞,也就是訊號屏蔽字(或阻塞訊號集)中的對應位元被置為1。阻塞訊號集和未決訊號集都是由內核維護的。整個過程如下圖所示:

詳解Linux訊號集操作函數

我們有時需要屏蔽某個訊號,就需要去修改阻塞訊號集。那麼,我們該如何修改阻塞訊號集呢?系統提供的一個方法是,我們先建立一個跟阻塞訊號集一樣的集合,再利用它去修改阻塞訊號集。

系統提供了一系列的訊號集設定函數。這些函數如下所示:

sigset_t  set;

信号集数据类型,本质是typedef unsigned long sigset_t; 

int sigemptyset(sigset_t *set);

将某个信号集清0

int sigfillset(sigset_t *set);

将某个信号集置1

int sigaddset(sigset_t *set, int signum);

将某个信号加入信号集

int sigdelset(sigset_t *set, int signum);

将某个信号清出信号集

以上几个函数返回值均是:成功:0;失败:-1

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

判断某个信号是否在信号集中

返回值:在集合:1;不在:0;出错:-1

使用以上這些函數建立完訊號集後,要如何改變阻塞訊號集呢?系統又提供了一個函數:sigprocmask函數。 sigprocmask函數可以用來屏蔽訊號,也可以用來解除屏蔽訊號,其本質就是利用我們所建立的訊號集去改變阻塞訊號集。

函數原型:

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

傳回值:

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

參數解釋:

set:傳入參數,是一個位圖,set中哪位置1,就表示目前進程屏蔽哪個訊號。

oldset:傳出參數,保存舊的訊號屏蔽集。這個與setitimer有點相似。

how參數取值:

假設目前的訊號屏蔽字為mask

1.SIG_BLOCK:當how設定為此值,set表示需要屏蔽的訊號。相當於 mask = mask | set

2.SIG_UNBLOCK:當how設定為此,set表示需要解除屏蔽的訊號。相當於 mask = mask & ~set

3.SIG_SETMASK:當how設定為此,set表示用來取代原始屏蔽及的新屏蔽集。相當於 mask = set若,呼叫sigprocmask解除了對目前若干個訊號的阻塞,則在sigprocmask回傳前,至少將其中一個訊號遞達。

我們如何讀取未決訊號集?系統提供了sigpending函數。

函數原型:

int sigpending(sigset_t *set);

參數說明:

set傳出參數。

傳回值:

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

範例:把所有常規訊號的未決狀態列印至螢幕。

#include 
#include 
#include 

void printPending(sigset_t *set)
{
    int i = 0;

    for (i = 0; i if (sigismember(set, i) == 1)
            printf("1");
        else
            printf("0");
    }
    printf("\n");
}

int main()
{
    sigset_t set, oldset, pendset;
    sigemptyset(&set);
    sigaddset(&set, SIGQUIT);   // ctrl + \ 将产生SIGQUIT信号
    sigprocmask(SIG_BLOCK, &set, &oldset);
    while (1) {
        sigpending(&pendset);
        printPending(&pendset);     // 写一个函数打印未决信号集
        sleep(1);
    }
}

以上是詳解Linux訊號集操作函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:lxlinux.net。如有侵權,請聯絡admin@php.cn刪除