Linux訊號機制之sigaction結構體淺析
訊號安裝函式sigaction(int signum,const struct sigaction *act,struct sigaction *oldact)的第二個引數是一個指向sigaction結構的指標(結構體名稱與函式名一樣,千萬別弄混淆了)。在結構sigaction的例項中,指定了對特定訊號的處理,訊號所傳遞的資訊,訊號處理函式執行過程中應遮蔽掉哪些函式等。當然,此指標也可以為NULL,程序會以預設方式處理訊號。以下就簡單介紹一下sigaction結構以及一般的用法。
對於核心標頭檔案而言,struct sigaction 結構體定義在kernel/include/asm/signal.h,此標頭檔案又被kernel/include/linux/signal.h包含。
對於使用者空間的標頭檔案而言,struct sigaction定義在 /usr/include/bits/sigaction.h,此標頭檔案又被/usr/include/signal.h包含,所以應用程式中如果用到此結構,只要#include <signal.h>即可。注意核心中的定義和應用程式中的定義是不一樣的,核心空間的sigaction結構只支援函式型別為__sighandler_t的訊號處理函式,不能處理訊號傳遞的額外資訊。具體定義如下:
/* Type of a signal handler. */
typedef void (*__sighandler_t)(int);
#ifdef __KERNEL__
struct old_sigaction {
__sighandler_t sa_handler;
old_sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
struct sigaction {
__sighandler_t sa_handler;
unsigned long sa_flags;
void (*sa_restorer)(void);
sigset_t sa_mask; /* mask last for extensibility */
};
struct k_sigaction {
struct sigaction sa;
};
#else
/* Here we must cater to libcs that poke about in kernel headers. */
struct sigaction {
union {
__sighandler_t _sa_handler;
void (*_sa_sigaction)(int, struct siginfo *, void *);
} _u;
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
#define sa_handler _u._sa_handler
#define sa_sigaction _u._sa_sigaction
#endif /* __KERNEL__ */
sa_handler的原型是一個引數為int,返回型別為void的函式指標。引數即為訊號值,所以訊號不能傳遞除訊號值之外的任何資訊;
sa_sigaction的原型是一個帶三個引數,型別分別為int,struct siginfo *,void *,返回型別為void的函式指標。第一個引數為訊號值;第二個引數是一個指向struct siginfo結構的指標,此結構中包含訊號攜帶的資料值;第三個引數沒有使用。
sa_mask指定在訊號處理程式執行過程中,哪些訊號應當被阻塞。預設當前訊號本身被阻塞。
sa_flags包含了許多標誌位,比較重要的一個是SA_SIGINFO,當設定了該標誌位時,表示訊號附帶的引數可以傳遞到訊號處理函式中。即使sa_sigaction指定訊號處理函式,如果不設定SA_SIGINFO,訊號處理函式同樣不能得到訊號傳遞過來的資料,在訊號處理函式中對這些資訊的訪問都將導致段錯誤。
sa_restorer已過時,POSIX不支援它,不應再使用。
因此,當你的訊號需要接收附加資訊的時候,你必須給sa_sigaction賦訊號處理函式指標,同時還要給sa_flags賦SA_SIGINFO,類似下面的程式碼:
#include <signal.h>
……
void sig_handler_with_arg(int sig,siginfo_t *sig_info,void *unused){……}
int main(int argc,char **argv)
{
struct sigaction sig_act;
……
sigemptyset(&sig_act.sa_mask);
sig_act.sa_sigaction=sig_handler_with_arg;
sig_act.sa_flags=SA_SIGINFO;
……
}
如果你的應用程式只需要接收訊號,而不需要接收額外資訊,那你需要的設定的是sa_handler,而不是sa_sigaction,你的程式可能類似下面的程式碼:
#include <signal.h>
……
void sig_handler(int sig){……}
int main(int argc,char **argv)
{
struct sigaction sig_act;
……
sigemptyset(&sig_act.sa_mask);
sig_act.sa_handler=sig_handler;
sig_act.sa_flags=0;
……
}
例:
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
sigset_t set,pendset;
struct sigaction action;
//清空訊號集
sigemptyset(&set);
//加入SIGTERM呢個訊號
sigaddset(&set,SIGTERM);
//設為阻塞
sigprocmask(SIG_BLOCK,&set,NULL);
//因為阻塞所以就算用kill傳送訊號都無反應
kill(getpid(),SIGTERM);
//查下有什麼阻塞訊號,裝入&pendset裡面
sigpending(&pendset);
//看下面有什麼訊號在裡面
if(sigismember(&pendset,SIGTERM))
{
printf("yes,the SIGTERM is here\n");
//清空阻塞訊號集
sigemptyset(&action.sa_mask);
//訊號涵數處理為ignore(忽略)
action.sa_handler=SIG_IGN;
//啟動同signal功能類的訊號涵數
sigaction(SIGTERM,&action,NULL);
}
//解除之前的訊號阻塞
sigprocmask(SIG_UNBLOCK,&set,NULL);
exit(EXIT_SUCCESS);
}
附:Linux C常用函式http://man.chinaunix.net/develop/c&c++/linux_c/default.htm
相關推薦
Linux訊號機制之sigaction結構體淺析
訊號安裝函式sigaction(int signum,const struct sigaction *act,struct sigaction *oldact)的第二個引數是一個指向sigaction結構的指標(結構體名稱與函式名一樣,千萬別弄混淆了)。在結構sigaction的例項中,指定了對特定訊號的處理
FFmpeg-4.0 的filter機制的架構與實現.之二 結構體關係與定義
4. Filter的結構體關係圖與定義 4.1 結構體間的關係圖 filter涉及的結構體,主要包括: > FilterGraph, AVFilterGraph > InputFilter, InputStream, OutputFilter, OutputStream
閱讀Linux裝置驅動模型原始碼之 device結構體成員詳解
【前言】 我們學習 Linux 裝置驅動,很多人在一開始往往急於想找到快速入門的方法,希望能有一個提綱挈領的使用說明來幫助我們快速理解 Linux 裝置驅動的設計思路和框架,從而擺脫掉 Linux 核心這頭龐然怪獸。我自己最初也是這樣。然而事與願違,如果學習
linux同步機制之訊號量down 和up
訊號量(semaphore) Linux核心的訊號量在概念和原理上和使用者態的System V的IPC機制訊號量是相同的,不過他絕不可能在核心之外使用,因此他和System V的IPC機制訊號量毫不相干。 訊號量在建立時需要設定一個初始值,表示同時能有幾個任務能訪問
xenomai核心解析之訊號signal(一)---Linux訊號機制
版權宣告:本文為本文為博主原創文章,轉載請註明出處。如有錯誤,歡迎指正。部落格地址:https://www.cnblogs.com/wsg1100/ [TOC] ## 1. Linux訊號 >涉及硬體底層,本文以X86平臺講解。 訊號是事件發生時對程序的通知機制,是作業系統提供的一種軟體中斷。訊
LINUX 訊號機制【列表】
LINUX 訊號機制【列表】 訊號本質 訊號是在軟體層次上對中斷機制的一種模擬,在原理上,一個程序收到一個訊號與處理器收到一箇中斷請求可以說是一樣的。訊號是非同步的,一個程序不必通過任何操作來等待訊號的到達,事實上,程序也不知道訊號到底什麼時候到達。 訊號是程序間通訊機制中唯一
tty驅動之tty_operations結構體詳解
struct tty_operations { struct tty_struct * (*lookup)(struct tty_driver *driver, struct inode *inode, int idx); //返回
STL原始碼分析之pair結構體
前言 前面在分析set, RB-tree都有在insert實現中出現pair, 下節分析map的時候更會經常出現pair, 所以打算在之前先對pair有個認識. pair是一個有兩個變數的結構體, 即誰都可以直接呼叫它的變數, 畢竟struct預設許可權都是public, 將兩個
linux 訊號signal和sigaction理解
今天看到unp時發現之前對signal到理解實在淺顯,今天拿來單獨學習討論下。 signal,此函式相對簡單一些,給定一個訊號,給出訊號處理函式則可,當然,函式簡單,其功能也相對簡單許多,簡單給出個函式例子如下: 1 #incl
linux同步機制之互斥鎖
版權宣告:如有需要,可供轉載,但請註明出處:https://blog.csdn.net/City_of_skey/article/details/85494572 目錄 1、簡介 2、API 2.1 pthread_mutex_init 2.2 pt
OpenCV參考手冊之CvCapture結構體
1、CvCapture結構體: CvCapture是一個結構體,用來儲存影象捕獲的資訊,就像一種資料型別(如int,char等)只是存放的內容不一樣,在OpenCv中,它最大的作用就是處理視訊時(程式是按一幀一幀讀取),讓程式讀下一幀的位置,CvCapture結構中,每獲取
網路驅動移植之sk_buff結構體及其相關操作函式(下)
2、結構體相關操作函式 (1)、dev_alloc_skb 實際上,函式dev_alloc_skb最終是呼叫__alloc_skb函式來分配資料緩衝區和sk_buff結構體的,如下圖: 從dev_alloc_skb到__alloc_skb
Linux中的struct stat 結構體和 stat() 函式
根據下面的連結,直接看使用 struct stat 結構體和 stat() 函式的程式: 對於 struct stat 結構體型別的 buf 變數中的 st_size 的資料型別,根據網上查到的資料,在64位系統下為 long long int 型別,所以我們將該變數進行
Linux訊號機制分析和訊號處理函式
【摘要】本文分析了Linux核心對於訊號的實現機制和應用層的相關處理。首先介紹了軟中斷訊號的本質及訊號的兩種不同分類方法尤其是不可靠訊號的原理。接著分析了核心對於訊號的處理流程包括訊號的觸發/註冊/執行及登出等。最後介紹了應用層的相關處理,主要包括訊號處理函式的安裝、訊號
【Linux】淺談Linux下的PCB—task_struct結構體
1.1 程序的概念 我之前在作業系統這門課中學過的有關程序的概念如下: 從作業系統層面上講:程序是程式的一次執行過程,是系統進行資源分配和處理機排程的一個獨立單位。程序的結構特性:程序=程式段+資料段+程序控制塊。程序的三種基本狀態: · 就緒
Linux中斷機制之三:中斷的執行
在核心程式碼中,對X86平臺中斷執行的基本過程是: 1、 通過IDT中的中斷描述符,呼叫common_interrupt; 2、 通過common_interrupt,呼叫do_IRQ,完成vector到irq_desc的轉換,進入Generic int
Linux核心同步機制之訊號量和互斥體
訊號量:訊號量(semaphore)是程序間通訊處理同步互斥的機制。是在多執行緒環境下使用的一種措施,它負責協調各個程序,以保證他們能夠正確、合理的使用公共資源。 它和spin lock最大的不同之處就是:無法獲取訊號量的程序可以睡眠,因此會導致系統排程。原理訊號量一般可以用
【2017-07-01】Linux應用開發工程師面試問題記錄之二:關於結構體的大小及內存對齊問題
偶數 而且 strong span net 但是 開發 f11 flag Tencent後臺服務器開發有一道題是計算一個結構體的sizeof的大小: struct strData { int m_Int; char m_Char; short m_Short; char
Linux 驅動之塊裝置結構體 (二)
上回最後面介紹了相關資料結構,下面再詳細介紹 塊裝置物件結構 block_device 核心用結構block_device例項代表一個塊裝置物件,如:整個硬碟或特定分割槽。如果該結構代表一個分割槽,則其成員bd_part指向裝置的分割槽結構。如果該結構代表裝置,則其成員
linux系統程式設計之struct flock 結構體
該結構是在lock.h檔案中定義。 lock.h File 功能 定義一些檔案的鎖的選項 Description The flockstructure in the/usr/include/s