![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
信號處理函數(shù)signal()和信號集函數(shù)組 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
本文關(guān)鍵字: 信號處理函數(shù),signal(),信號集函數(shù)組 信號處理的方法主要有兩種,一種是使用signal()函數(shù),另一種是使用信號集函數(shù)組。下面分別介紹這兩種處理方式。 1)使用signal()函數(shù) 使用signal()函數(shù)處理時(shí),只需指出要處理的信號和處理函數(shù)即可。它主要用于前32種非實(shí)時(shí)信號的處理,不支持信號傳遞信息,但是由于使用簡單、易于理解,因此也受到很多程序員的歡迎。Linux還支持一個(gè)更健壯更新的信號處理函數(shù)sigaction(),推薦使用該函數(shù)。 signal()函數(shù)的語法要點(diǎn)如表1所示。 表1 signal()函數(shù)語法要點(diǎn)
這里需要對該函數(shù)原型進(jìn)行說明。這個(gè)函數(shù)原型有點(diǎn)復(fù)雜:首先該函數(shù)原型整體指向一個(gè)無返回值并且?guī)б粋(gè)整型參數(shù)的函數(shù)指針,也就是信號的原始配置函數(shù);接著該原型又帶有兩個(gè)參數(shù),其中第2個(gè)參數(shù)可以是用戶自定義的信號處理函數(shù)的函數(shù)指針。 表2列舉了sigaction()函數(shù)的語法要點(diǎn)。 表2 sigaction()函數(shù)語法要點(diǎn)
這里要說明的是sigaction()函數(shù)中第2和第3個(gè)參數(shù)用到的sigaction結(jié)構(gòu),這是一個(gè)看似非常復(fù)雜的結(jié)構(gòu),希望讀者能夠慢慢閱讀此段內(nèi)容。 首先給出了sigaction的定義,代碼如下: struct sigaction sa_handler是一個(gè)函數(shù)指針,指定信號處理函數(shù),這里除可以是用戶自定義的處理函數(shù)外,還可以為SIG_DFL(采用默認(rèn)的處理方式)或SIG_IGN(忽略信號)。它的處理函數(shù)只有一個(gè)參數(shù),即信號值。 sa_mask是一個(gè)信號集,它可以指定在信號處理程序執(zhí)行過程中哪些信號應(yīng)當(dāng)被屏蔽,在調(diào)用信號捕獲函數(shù)前,該信號集要加入到信號的信號屏蔽字中。 sa_flags中包含了許多標(biāo)志位,是對信號進(jìn)行處理的各個(gè)選擇項(xiàng)。它的常見可選值如表3所示。 表3 常見信號的含義及其默認(rèn)操作
以下實(shí)例表明了如何使用signal()函數(shù)捕捉相應(yīng)信號,并做出給定的處理。這里,my_func就是信號處理的函數(shù)指針,讀者還可以將其改為SIG_IGN或SIG_DFL查看運(yùn)行結(jié)果。第2個(gè)實(shí)例是用sigaction()函數(shù)實(shí)現(xiàn)同樣的功能。 以下是使用signal()函數(shù)的示例: /* signal.c */ 運(yùn)行結(jié)果如下: $ ./signal 以下是用sigaction()函數(shù)實(shí)現(xiàn)同樣的功能,只列出了更新的main()函數(shù)部分。 /* sigaction.c */ 2)信號集函數(shù)組 使用信號集函數(shù)組處理信號時(shí)涉及一系列的函數(shù),這些函數(shù)按照調(diào)用的先后次序可分為以下幾大功能模塊:創(chuàng)建信號集、注冊信號處理函數(shù)及檢測信號。 其中,創(chuàng)建信號集主要用于處理用戶感興趣的一些信號,其函數(shù)包括以下幾個(gè)。 ● sigemptyset():將信號集初始化為空。 ● sigfillset():將信號集初始化為包含所有已定義的信號集。 ● sigaddset():將指定信號加入到信號集中。 ● sigdelset():將指定信號從信號集中刪除。 ● sigismember():查詢指定信號是否在信號集中。 注冊信號處理函數(shù)主要用于決定進(jìn)程如何處理信號。這里要注意的是,信號集里的信號并不是真正可以處理的信號,只有當(dāng)信號的狀態(tài)處于非阻塞狀態(tài)時(shí)才會(huì)真正起作用。因此,首先使用sigprocmask()函數(shù)檢測并更改信號屏蔽字(信號屏蔽字是用來指定當(dāng)前被阻塞的一組信號,它們不會(huì)被進(jìn)程接收),然后使用sigaction()函數(shù)來定義進(jìn)程接收到特定信號后的行為。 檢測信號是信號處理的后續(xù)步驟,因?yàn)楸蛔枞男盘柌粫?huì)傳遞給進(jìn)程,所以這些信號就處于“未處理”狀態(tài)(也就是進(jìn)程不清楚它的存在)。sigpending()函數(shù)允許進(jìn)程檢測“未處理”信號,并進(jìn)一步?jīng)Q定對它們做何處理。 首先介紹創(chuàng)建信號集的函數(shù)格式,表4列舉了這一組函數(shù)的語法要點(diǎn)。 表4 創(chuàng)建信號集函數(shù)語法要點(diǎn)
表5列舉了sigprocmask()函數(shù)的語法要點(diǎn)。 表5 sigprocmask()函數(shù)語法要點(diǎn)
此處,若set是一個(gè)非空指針,則參數(shù)how表示函數(shù)的操作方式;若how為空,則表示忽略此操作。 表6列舉了sigpending()函數(shù)的語法要點(diǎn)。 表6 sigpending()函數(shù)語法要點(diǎn)
總之,在處理信號時(shí),一般遵循如圖1所示的操作流程。
本文選自華清遠(yuǎn)見嵌入式培訓(xùn)教材《從實(shí)踐中學(xué)嵌入式Linux應(yīng)用程序開發(fā)》 熱點(diǎn)鏈接:
1、信號捕捉函數(shù)alarm()和pause() |