Linux程式設計複習 3 訊號與中斷

2021-10-06 10:26:14 字數 4241 閱讀 9647

訊號是響應某些狀況而產生的事件,程序在接收到訊號時會採取相應的行動。某些狀況就是指某些條件錯誤,如記憶體段衝突、浮點處理器錯誤或者非法指令等。訊號是在軟體層次上對中斷的一種模擬,所以訊號也稱為是軟中斷

訊號與中斷的相似點:

1,都採用相同的額非同步通訊方式

2,當檢測出有訊號或中斷請求時,都暫停證在執行的程式而轉去執行相應的處理程式

3,都在處理完畢之後返回到原來的斷點

4,對訊號或中斷都可進行遮蔽

訊號與中斷的區別:

1,中斷有優先順序,而訊號沒有,所有的訊號都是平等的

2,訊號處理程式是在使用者態下執行的,而中斷處理程式是在核心態下執行的

3,中斷響應是及時的,而訊號響應通常都有較大的事件延遲

程序對訊號的三種響應:

1,忽略訊號,除了sigkill,sigstop

2,捕獲並處理訊號,核心中斷正在執行的**,轉去執行先前註冊處

3,執行預設操作,預設操作通常是終止程序,取決於被傳送的訊號

中斷乙個中斷處理程式到系統中__sighandler_t signal(iny signum, __sighandler_t handler);signal是乙個帶signum和handler兩個引數的函式,準備捕捉或遮蔽的訊號由signum給出,接收到指定訊號時將要呼叫的函式由handler給出;

handler這個函式必須有乙個int型別的引數,即接收到的訊號**,當然handler也可以是sig_ign(遮蔽該訊號)、sig_dfl(恢復預設行為)這兩個特殊值

超簡單例子?

sigint對應鍵盤ctrl+c發出的訊號

#include

2 #include

3 #include

4 #include

5 #include

67 #include

8 #include

9 #include

10 #include

11 #include

1213 #define err_exit

(m) \

14do \

15while(0

)1920void

handler

(int sig);21

22int

main

(int argc,

char

*ar**)

2328

void

handler

(int sig)

29

結果?

1,執行訊號的處理動作稱為訊號遞達,訊號產生到遞達之間的狀態稱為訊號未決,程序可以選擇阻塞某個訊號。被阻塞的訊號產生時將保持在未決狀態,直到程序解除對此訊號的阻塞,才執行遞達的動作。

訊號集操作函式:

#include

int sigemptyset(sigset_t* set);

int sigfillset(sigset_t *set);

int sigaddset(sigset_t * set, int_signo);

int sigdelset(sigset_t* set, int signo);

int sigismember(const sigset_t *set, int signo);

獲取/改變 程序中的訊號遮蔽字:int sigprocmask(int how, const sigset_t *set, sigset_t *oset)第三個引數是改變之前的訊號遮蔽字的狀態,第乙個引數改變方式有三種sig_blocksig_unblocksig_setmask

sigpending(&set)函式可以獲取程序中的未決訊號集合儲存到set中

例子?訊號從產生到遞達的乙個過程

bset將sig_init進行阻塞,但接收到sig_quit即ctrl/時取消阻塞,始終用函式將未決訊號集列印出來

設定阻塞或者取消阻塞都是要用自定義的乙個set來進行sigprocmask來設定的

16

void

printsigset

(sigset_t *set)

//列印未決訊號集內容

1726

printf

("\n");

27}28void

handler

(int sig);29

intmain

(int argc,

char

*ar**)

3044

4546

return0;

47}4849

void

handler

(int sig)

5060

}

int sigaction(int signum, const struct sigaction *act, const struct sigaction *old)第二個引數最為重要,其中包含了對指定訊號的處理、訊號所傳遞的資訊、訊號處理函式執行過程中應遮蔽掉哪些訊號等

struct sigaction
handler包含在sigaction這個結構體中?

void

handler

(int sig);29

intmain

(int argc,

char

*ar**)

3042

void

handler

(int sig)

43

關於sa_mask,指定訊號掩碼,在乙個訊號執行過程中,sa_mask中的訊號發生了也不會遞達,會被阻塞直到真正該執行的訊號函式結束

在sa_mask中加入sigquit訊號,那麼在sigint捕捉到執行handler的過程中,發生sa_mask中的訊號也會被遮蔽

int

main

(int argc,

char

*ar**)

3043

void

handler

(int sig)

44

sa_flags的用法有需要再補吧233

三種不同精度的睡眠

1,unisigned int sleep(uninsigned int seconds);,返回剩餘秒數while(n = sleep(n))

2,int usleep(useconds_t usec);微秒

3,int nanosleep(const struct timepec *req, struct timespec *rem);納秒,第二個引數時剩餘睡眠時間

三種不同精度就對應三種時間結構

getitimer()/setitimer()功能描述:

獲取或設定間歇計時器的值。系統為程序提供三種型別的計時器,每一類以不同的時間域遞減其值。當計時器超時,訊號被傳送到程序,之後計時器重啟動。

用法:

#include

intgetitimer

(int which,

struct itimerval *value)

;int

setitimer

(int which,

const

struct itimerval *value,

struct itimerval *ovalue)

;

引數:

which:間歇計時器型別,有三種選擇

itimer_real //數值為0,計時器的值實時遞減,傳送的訊號是sigalrm。

itimer_virtual //數值為1,程序執行時遞減計時器的值,傳送的訊號是si**talrm。

itimer_prof //數值為2,程序和系統執行時都遞減計時器的值,傳送的訊號是sigprof。

LINUX中斷機制與訊號

在學習apue時學習訊號程式設計,很多地方不是理解,便查閱了網路上的相關資料,最常見的一句話就是 訊號是中斷機制的一種模擬 既然提到了中斷,那就首先了解了一下中斷的具體分類以及實現,最後再找出中斷和訊號的區別。l 中 斷 也稱硬體中斷 定義 中斷是由其他硬體裝置依照cpu 時鐘週期訊號隨機產生的。分...

訊號與中斷

訊號是系統為了響應某些狀況而產生的事件,程序收到訊號後應該採取相應的動作。用來通知程序發生了非同步事件。訊號與中斷的相似點 1 採用了相同的非同步通訊方式 2 當檢測出有訊號或中斷請求時,都暫停正在執行的程式而轉去執行相應的處理程式 3 都在處理完畢後返回到原來的斷點 4 對訊號或中斷都可進行遮蔽 ...

Linux程式設計 訊號

訊號 就是軟體中斷。訊號提供了一種處理非同步事件的方法 終端使用者鍵入中斷鍵,則會通過訊號機構停止乙個程式。所以,訊號可以說是程序控制的一部分。訊號的名字都以三個字母開頭 sig 訊號是非同步事件的經典例項。l 當使用者按某些終端鍵時,產生訊號。l 硬體異常產生訊號 除數為0 無效的儲存訪問等等。l...