Linux訊號 五 訊號掛起與訊號掩碼操作介面集
阿新 • • 發佈:2018-11-17
A signal may be blocked, which means that it will not be delivered until it is later unblocked. Between the time when it is generated and when it is delivered a signal is said to be pending. 訊號可以被阻塞,除非阻塞被解除否則不能將訊號傳遞給程序。從訊號產生到訊號被解除 阻塞這一段時間稱之為掛起。 Each thread in a process has an independent signal mask, which indicates the set of signals that the thread is currently blocking. 程序內的每個執行緒都有一個獨立的訊號掩碼,訊號掩碼是一組訊號集合,表明當前執行緒 阻塞的訊號。
Linux提供了一個新的資料結構用來實現訊號掩碼的功能:訊號集。多個訊號組成的集合被稱為訊號集,其資料型別為sigset_t。在Linux的實現中,sigset_t型別是位掩碼,每一個位元代表一個訊號。
相關操作介面包括訊號集初始化、新增、刪除、設定訊號掩碼等:
sigemptyset, sigfillset, sigaddset, sigdelset, sigismember sigprocmask, pthread_sigmask #include <signal.h> /** * 初始化一個空的未包含任何訊號的訊號集。 * 成功返回0,失敗返回-1並置errno */ int sigemptyset(sigset_t *set); /** * 初始化一個包含任何訊號的訊號集。 * 成功返回0,失敗返回-1並置errno */ int sigfillset(sigset_t *set); /** * 向訊號集中新增一個訊號。 * 成功返回0,失敗返回-1並置errno */ int sigaddset(sigset_t *set, int signum); /** * 從訊號集中刪除一個訊號。 * 成功返回0,失敗返回-1並置errno */ int sigdelset(sigset_t *set, int signum); /** * 判斷該訊號是否在訊號集中 * 屬於返回1,不屬於返回0,出錯返回-1並置errno */ int sigismember(const sigset_t *set, int signum); /** * 將當前執行緒的訊號集讀取到set結構體中 * 成功返回0,失敗返回-1並置errno */ int sigpending(sigset_t *set); Glibc擴充套件函式 如果定義了 _GNU_SOURCE 巨集,signal.h還提供了額外三個引數用於操作訊號集,不過 這些都是非標準的函式(其它系統可能有類似的實現),不能用於移植程式的開發中 /** * 判斷訊號集是否為空 * 為空返回1,否則返回0 */ int sigisemptyset(const sigset_t *set); /** * 取left 和 right的並集,並存儲到dest結構體中 * 成功返回0,失敗返回-1並置errno */ int sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right); /** * 取left 和 right的交集,並存儲到dest結構體中 * 成功返回0,失敗返回-1並置errno */ int sigandset(sigset_t *dest, const sigset_t *left, const sigset_t *right); /** * 獲取或設定程序的阻塞訊號掩碼 * * 根據引數how的值,提供了三種用於改變程序的阻塞訊號掩碼方式 * * SIG_BLOCK:新的程序訊號掩碼是當前訊號掩碼與set指向訊號集的並集,相當於在當前訊號集 * 掩碼中增加set的訊號。 * * SIG_UNBLOCK: 新的程序訊號掩碼是當前訊號掩碼與set指向訊號集的補集的交集,相當於從 * 當前訊號掩碼中刪除set中訊號,解除對其的遮蔽。 * * SIG_SETMASK : 直接把程序的訊號掩碼設定成set指向的訊號集。 * * 如果引數oldset不為NULL,之前的訊號掩碼配置將會儲存到該指標中。 * 如果引數set為NULL的話,相當於不做任何改變。 * * 另外多執行緒中使用該函式的結果將是未定義的,多執行緒中最好使用pthread_sigmask()介面 * * 成功返回0,失敗返回-1並置errno */ #include <signal.h> int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); /** * 該函式功能和sigprocmask一樣,只不過是用在多執行緒中,用於改變呼叫執行緒的訊號掩碼集。 * * 成功返回0,失敗返回錯誤碼,編譯連結的時候加上-pthread選項。 */ #include <signal.h> int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
參考資料
1. 《Linux環境程式設計,從應用到核心》高峰,李彬著
2. man signal : http://www.man7.org/linux/man-pages/man7/signal.7.html
man sigsetops : http://www.man7.org/linux/man-pages/man3/sigsetops.3.html