POSIX訊號處理

2021-06-19 03:37:41 字數 3463 閱讀 8840

posix訊號處理

一. 訊號的安裝(signal和signalaction)

typedef  void  (signal_handler)(int signo);

signal_handler *signal(int signo, signal_handler *sigfunc);

int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);

siganl和sigaction都是用來安裝訊號的。但是:

1)訊號分為實時/可靠訊號和非實時/不可靠訊號兩種。實時訊號都是可靠的,不實時訊號都是不可靠的。

2)不可靠訊號的訊號處理函式的形式只能是:void sighandler(int);

可靠訊號的訊號處理函式除了可以和不可靠訊號的出來函式一樣之外,還可以是 void sighandler(int, siginfo_t *, void *);

3)使用siganl函式安裝的訊號的訊號處理函式只能是void sighandler(int),無論是可靠訊號還是不可靠訊號;

只有使用sigaction訊號安裝的訊號的處理函式才可以是void sighandler(int, siginfo_t *, void *),但是只有可靠訊號才有可能又這種待遇~

在signal函式中,第乙個引數signo是要安裝的訊號編號,第二個引數是訊號處理函式的指標。這個函式比較簡單。

在sigaction函式中,有兩個引數都是struct sigaction*型別的。這個結構體大概如下(一些系統的實現可能還包含一些其他成員):

struct sigaction ;

sa_handler:是乙個普通訊號處理函式的指標,可靠訊號和不可靠訊號都可以使用。

sa_sigaction:是乙個可靠訊號處理函式的指標,只有可靠訊號可能用得到。

sa_mask:指定執行訊號處理函式時要阻塞的訊號集。posix規定,訊號處理函式在執行時會預設自動阻塞當前訊號本身。

sa_flags:是乙個可以指定很多種標誌的變數。比如說,可以在sa_flags指定no_mask取消所有訊號的阻塞,包括當前訊號本身。此外,還有乙個很重要的標誌,sa_siginfo。只有當這個標誌被置位時,sa_sigaction才允許被傳送更多的引數。當然,並不是說使用了sa_siginfo就必須使用sa_sigaction。(要了解sa_flags,就在linux下man一下sigaction)

寫到這裡,我發現有兩個問題:

1)void sa_sigaction(int, siginfo_t *, void *)的另外兩個引數從**來?這裡似乎看不出。我也看不出。

2)到底實時/可靠訊號和非實時/不可靠訊號之間有什麼關係?有什麼區別?

二.訊號的種類

介紹訊號,這個本來應該是寫在最前面的才對。無奈我沒注意~在這裡補充一下。

上面說了,訊號分為:1.實時/可靠的; 2.非實時/不可靠的。

1.實時訊號,也就是可靠訊號是訊號值位於區間[sigrtmin, sigrtmax]的訊號。這種訊號的特點是:

1)支援排隊,不會丟失。訊號支援排隊是什麼意思呢?我們知道訊號是可以阻塞的(sigstop和sigkill例外),

我們假設可靠信 號s1在被阻塞的過程發生了3次,那麼,這3次s1信      號都會排隊等待程序來處理,不會丟失。

2)訊號處理函式能夠支援三個引數(這個上面講過了)。

2.非實時,也就是不可靠訊號是訊號值小於sigrtmin的訊號。這種訊號的特點是:

1 )每次訊號出來完需要重新安裝。不過這個問題已經成為過去了~現在的siganl函式基本都是封裝sigaction函式得來的,

沒有這個問題。

2)訊號不支援排隊。和上面一樣的例子,如果訊號阻塞的過程中,s1產生3次,往往後面產生的2此都會被丟棄。

訊號處理函式只能有乙個引數。

三. 訊號的**

到目前為止,我們還沒有講到這些訊號到底是怎麼來的~

1. 訊號的**有:硬體**和軟體**兩種。我們的重點是討論軟體**。軟體**主要是一些能發生訊號的函式。這類函式有:kill\raise\alarm\settimmer\sigqueue\abort。

2. kill函式

#include

#include

int kill(pid_t pid, int sig);

kill函式的作用是傳送訊號sig給程序pid。

3. raise函式

#include

int raise(int sig);

raise函式傳送訊號sig給自身。

4. alarm函式

#include

unsigned int alarm(unsigned int seconds);

alarm函式的作用是定時seconds秒,時間到後傳送訊號sigalrm給程序。

返回值:0或者上一次定時剩下的秒數。

注意:

1)alarm與setitimer共用乙個定時器,會相互影響使用。

2)不要混用sleep和alarm。

3)核心會有排程延遲。

4. setitimer函式

#include

int setitimer(int which, const struct itimerval *new_value,  

struct itimerval *old_value);

setitimer函式和alarm一樣是設定定時器。但是setitimer設定的時間要根據精確。倒計時的方式也可以設定成多種。

which ---- 設定倒計時的方式:

itimer_real:根據核心真實時間倒計時。時間到傳送訊號sigalrm。

itimer_virtual:程序在使用者態執行時才進行倒計時。時間到傳送訊號sigvtalrm。

itimer_prof:程序在使用者態和核心態執行時都進行倒計時。時間到傳送訊號sigprof。

struct itimerval ;

struct timeval ;

new_value是用來設定定時器的結構體變數。it_value指定初始定時時間。it_interval用來在定時超時後重新初始化it_value。

old_value用來返回上乙個定時器的資料。

5)sigqueue函式

#include

int sigqueue(pid_t pid, int sig, const union sigval value);

sigqueue函式的作用和前兩個引數一樣。第三個引數用來向訊號處理函式傳遞乙個引數。

6)abort

void abort(void)

abort函式會導致程序異常退出。

posix 訊號處理

訊號signal就是告知某個程序傳送了某個事件的通知,有時也成為軟中斷。訊號是非同步發生的,即不知道其發生的準確時間。訊號可以 建立訊號處置的posix方法就是呼叫sigaction函式 typedef void sigfunc int sigfunc signal int signo,sigfun...

UNP卷一學習筆記 POSIX訊號處理

訊號是告知某個程序發生了某個事件的通知,也叫軟體中斷,通常是非同步發生的。訊號的傳遞 a程序 b程序或者核心 某個程序。當程序收到某一訊號,需要有個相應的處置 disposition 一般通過呼叫sigaction函式來設定對某個特定訊號的處置,並有三種選擇 1 為訊號提供乙個訊號處理函式,這種行為...

posix訊號量機制

posix為可移植的作業系統介面標準,定義了作業系統應該為應用程式提供的介面標準 訊號量機制是我們在作業系統中學到的知識,可以用來解決同步和互斥的問題,它只能被兩個標準的原語wait s 和signal s 來訪問,也就是p操作和v操作。訊號量的概念在system v 和posix 中都有,但是它們...