linux基礎 訊號阻塞及未決訊號

2021-10-02 14:25:45 字數 4614 閱讀 2821

未決訊號

pause的使用

訊號傳送處理過程

可重入函式

訊號處理函式的繼承

setitimer實現定時器

程序可以設定對某個訊號的阻塞(遮蔽),需要用到sigset_t(訊號集)資料型別。

sigemptyset(3)

#include 

int sigemptyset(sigset_t *set)

;功能:將訊號集清空

引數:set:指定要清空的訊號集

返回值:

0 成功

-1 錯誤

int sigfillset(sigset_t *set);

功能:將訊號集設定為滿

引數:set:指定要置滿的訊號集

返回值:

0 成功

-1 錯誤

int sigaddset(sigset_t *set, int signum);

功能:給訊號集新增訊號

引數:set:指定訊號集

signum:指定要新增的訊號

返回值:

0 成功

-1 錯誤

int sigdelset(sigset_t *set, int signum);

功能:刪除訊號集中的某個訊號

引數:set:指定訊號集

signum:指定要刪除的訊號

返回值:

0 成功

-1 錯誤

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

功能:測試訊號是否是訊號集中的乙個成員

引數:set:指定的訊號集

signum:指定訊號

返回值:

-1 錯誤

0 訊號不是訊號集中的乙個成員

1 訊號集中有這個訊號

如果希望設定程序對2號訊號阻塞,就需要設定阻塞訊號集

sigset_t block_set;

將block_set集合中的所有成員清空;

將2好訊號新增到block_set集合中;

將block_set設定為這個程序的阻塞訊號集。sigprocmask函式使用。

sigprocmask(2)

#include 

int sigprocmask(int how, const sigset_t *set, \

sigset_t *oldset)

;功能:檢測或改變阻塞訊號

引數:how:

sig_block 當前訊號集和set指定訊號集的並集

sig_unblock 將set集合裡的成員從當前程序阻塞訊號集中移除

sig_setmask 將set指定為當前程序的阻塞訊號集

set:指定的新的訊號集

oldset:之前的訊號集儲存到oldset中。

返回值:

0 成功

-1 錯誤

#include

#include

#include

void

doit

(int n)

intmain

(void

)//解除訊號阻塞

sigprocmask

(sig_unblock,

&block,

null);

return0;

}

在訊號則是期間,可以檢視未決訊號。

如何檢視未決訊號。使用sigpending(2)檢視

#include 

int sigpending(sigset_t *set)

;功能:檢測未決訊號

引數:set:值-結果引數,用於返回程序的未決訊號掩碼

返回值:

0 成功

-1 錯誤

#include

#include

intmain

(void)if

(f==0)

else

int f3=

sigismember

(&p,3)

;if(f3==-1

)if(f3==0)

else

}return0;

}

int pause(void);

#include 

int pause(void)

;功能:等待乙個訊號

引數:void

返回值:

-1 錯誤 errno被設定為eintr

#include

#include

#include

void

doit

(int n)

intmain

(void)*/

printf

("pause after...%d\n"

,f);

return0;

}

#include

#include

#include

void

doit

(int n)

unsigned

intmysleep

(unsigned

int seconds)

intmain

(void

)return0;

}

使用者輸入命令,在bash下啟動乙個前台作業。

使用者按下ctrl+c鍵,這個鍵盤輸入產生乙個硬體中斷。

如果cpu正在執行這個程序的**,則該程序的使用者空間**暫停執行。cpu從使用者態切換到核心態處理硬體中斷。

終端驅動程式將ctrl+c解釋成乙個sigint訊號,記錄在該程序的pcb中。

當某個時刻,程序從核心態切換會使用者態的時候,首先處理pcb中記錄的訊號,如果pcb中有未處理訊號,找到訊號對應的訊號處理程式進行處理。

訊號處理函式處理完畢,呼叫sigreturn(2),繼續返回到程序的核心態。再次迴圈到第五步。

函式使用到的變數的空間全部分配在棧楨中,那這樣的函式稱為可重入函式。否則稱為不可重入函式。

訊號的處理函式盡量保證為可重入函式。

#include

#include

void

doit

(int n)

intmain

(void

)

子程序會繼承父程序的訊號處理函式,訊號屬於程序資源,在程序的pcb中會有訊號的記錄。

#include

#include

#include

#include

#include

void

doit

(int n)

intmain

(void)if

(pid==0)

else

return0;

}

系統計時器,執行乙個程序的時候,程序所消耗的時間包括三個部分:

核心為每個程序都維護了三個計時器:

執行時間 = 使用者時間 + 核心時間 + 睡眠時間。

這三個計時器除了統計程序的各種時間以外,還可以按照各自的計時規則,以定時器的方式工作,向程序週期性的傳送不同的訊號。

sigalrm  真實定時器

si**talrm 虛擬定時器

sigprof 實用定時器

通過使用setitimer(2)設定、啟動、關閉定時器

#include 

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

struct itimerval *old_value)

;功能:設定乙個間隔時間的定時器

引數:which:

itimer_real:sigalrm

itimer_virtual:si**talrm

itimer_prof:sigprof

new_value:定時器新值

old_value:定時器原來的值

返回值:

0 成功

-1 錯誤 errno被設定

struct itimerval

;struct timeval

;

#include

#include

#include

#include

void

doit

(int n)

intmain

(void

)

linux訊號阻塞與未決

執行訊號的處理動作稱為訊號遞達 delivery 訊號從產生到遞達之間的狀態,稱為訊號未決 pending 程序可以選擇阻塞 block 某個訊號。被阻塞的訊號產生時將保持在未決狀態,直到程序解除對此訊號的阻塞,才執行遞達的動作。注意,阻塞和忽略是不同,只要訊號被阻塞就不會遞達,而忽略是在遞達之後可...

訊號「未決」與「阻塞」

訊號狀態 訊號的 未決 是一種狀態,指的是從訊號的產生到訊號被處理前的這一段時間 訊號的 阻塞 是乙個開關動作,指的是阻止訊號被處理,但不是阻止訊號產生。apue例題在sleep前用sigprocmask阻塞了退出訊號,然後sleep,然後在sleep的過程中產生乙個退出訊號,但是此時退出訊號被阻塞...

訊號「未決」與「阻塞」

訊號狀態 訊號的 未決 是一種狀態,指的是從訊號的產生到訊號被處理前的這一段時間 訊號的 阻塞 是乙個開關動作,指的是阻止訊號被處理,但不是阻止訊號產生。apue例題在sleep前用sigprocmask阻塞了退出訊號,然後sleep,然後在sleep的過程中產生乙個退出訊號,但是此時退出訊號被阻塞...