unix訊號使用總結:
訊號的原理:
訊號是一種程序通訊的方法,他應用於非同步事件的處理。訊號的實現是一種軟中斷。它被傳送為乙個正在執行的程序,已告知程序某個事件發生了。
1.1 訊號的建立:
用訊號處理來模擬作業系統的中斷功能。要想使用訊號處理功能,你要做的就是填寫乙個訊號處理函式即可。
(1)呼叫signal函式
函式原型如下:void signal(int signo,void * handler); signo是訊號型別,後面是訊號處理函式。
(2)呼叫kill函式
可以封裝乙個傳送訊號的函式:
int send_signal(pid_t pid, int sig)
return 0;
}
通過kill函式,對pid程序傳送訊號
(3)使用sigaction函式封裝signal
sigaction的結構如下:
struct sigaction
可以通過設定sigaction中的引數值獲得對sinal的封裝。
1.2訊號集操作
(1)訊號集的概念
在實際的應用中乙個應用程式需要對多個訊號進行處理,為了方便,linux系統引進了訊號集的概念。訊號集用多個訊號組成的資料型別sigset_t.可用以下的系統呼叫設定訊號集中所包含的資料。在系統中是這樣定義的:
typedef struct sigset_t;
(2)訊號集的操作
訊號集的操作
有以下幾種:
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigadd(sigset_t *set,int setnumber);
int sigdelset(sigset_t *set,int setnumber);
int sigismember(sigset_t *set,int setnumber);
使用方法:
通常使用sigemptyset函式初始化訊號集,然後呼叫sigadd新增需要處理的訊號,這樣才能對訊號進行阻塞等操作。
(3)訊號的阻塞
有時候不希望在接到訊號時就立即停止當前執行,去處理訊號,同時也不希望忽略該訊號,而是延時一段時間去呼叫訊號處理函式。這種情況是通過阻塞訊號實現的。阻塞的
概念和忽略訊號是不同的。作業系統在訊號被程序解除阻塞之前不會講訊號傳遞出去,被阻塞的訊號也不會影響程序的行為,訊號只是暫時被阻止傳遞。當程序忽略乙個訊號
時,訊號會被傳遞出去但程序會將訊號丟棄。需要注意當訊號被阻塞的時候,如果這種訊號發生了多次,在阻塞完成之後,只呼叫一次這種訊號,在阻塞過程中,這種訊號是
未決的。
訊號阻塞處理涉及到以下幾個函式:
1.sigprocmask函式
int sigprocmask(ubt how,const sigset_t*set,sigset_t *oldset);
sigprocmask設定對訊號遮蔽集內的訊號的處理方式(阻塞或不阻塞)。
引數:how:用於指定訊號修改的方式,可能選擇有三種
sig_block//將set所指向的訊號集中包含的訊號加到當前的訊號掩碼中。即訊號掩碼和set訊號集進行或操作。
sig_unblock//將set所指向的訊號集中包含的訊號從當前的訊號掩碼中刪除。即訊號掩碼和set進行與操作。
sig_setmask //將set的值設定為新的程序訊號掩碼。即set對訊號掩碼進行了賦值操作。
set:為指向訊號集的指標,在此專指新設的訊號集,如果僅想讀取現在的遮蔽值,可將其置為null。
oldset:也是指向訊號集的指標,在此存放原來的訊號集。可用來檢測訊號掩碼中存在什麼訊號。
返回說明:
成功執行時,返回0。失敗返回-1,errno被設為einval。
2.sigsuspend函式
int sigsuspend(const sigset_t *sigmask);
此函式用於程序的掛起,sigmask指向乙個訊號集。當此函式被呼叫時,sigmask所指向的訊號集中的訊號將賦值給訊號掩碼。之後程序掛起。直到程序捕捉到訊號,
並呼叫處理函式返回時,函式sigsuspend返回。訊號掩碼恢復為訊號呼叫前的值,同時將errno設為eintr。程序結束訊號可將其立即停止。
3.sigpending函式
次函式是判斷當前訊號是否處於未決狀態
1.3 wait()和waitpid()
wait和waitpid是處理僵死程序的函式,一般通過在while迴圈中使用這兩個函式來處理僵死程序。
例項:前面介紹了這麼多關於訊號的東西,下面看乙個例項:
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "signal.h"
char *id = "terminal\n";
int count = 0;
static void do_termal(int sig)
static void do_stop(int sig)
int main()
sigpending(&pendmask);
if (sigismember(&pendmask, sigtstp))
sleep(2);
} while (count < 5);
puts("end");
return 0;
}
**中註冊了兩個訊號處理函式,為ctrl_z,和ctrl_c處理,首先初始化sigaction結構中的各個成員,然後呼叫
sigemptyset(&sa_nact.sa_mask);
sigaddset(&sa_nact.sa_mask, sigtstp);
初始化訊號集,之後在count<=2的時候對ctrl_z block,當count>2解除block,程式執行中,如果在<2時,多次按ctrl_z,在unblock之後,只會執行一次ctrl_z處理
函式,其餘的訊號則被拋棄。
Linux C程式設計之訊號介紹
unix訊號使用總結 訊號的原理 訊號是一種程序通訊的方法,他應用於非同步事件的處理。訊號的實現是一種軟中斷。它被傳送為乙個正在執行的程序,已告知程序某個事件發生了。1.1 訊號的建立 用訊號處理來模擬作業系統的中斷功能。要想使用訊號處理功能,你要做的就是填寫乙個訊號處理函式即可。1 呼叫signa...
Linux C程式設計 訊號的傳送
前面介紹了linux中訊號的一些基本情況,這裡總結一下訊號的傳送。訊號的傳送主要由函式kill raise sigqueue alarm settimer abort 來完成。include include int kill pid t pid,int sig 關於第乙個引數,有如下注意 raise...
Linux C程式設計之 makefile使用
一,示例 四個檔案 main.c main.h t print.c t print.h makefile 寫法1 main main.o t print.o gcc main.o t print.o o main main.o main.c main.h gcc c main.c t print.o...