Linux C程式設計之訊號介紹

2021-06-05 04:25:50 字數 3101 閱讀 8429

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...