<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>
"); //-->

博客專(zhuān)欄

EEPW首頁(yè) > 博客 > Linux信號(signal)機制

Linux信號(signal)機制

發(fā)布人:電子禪石 時(shí)間:2021-06-18 來(lái)源:工程師 發(fā)布文章

信號(signal)是一種軟中斷,信號機制是進(jìn)程間通信的一種方式,采用異步通信方式

一、信號類(lèi)型

Linux系統共定義了64種信號,分為兩大類(lèi):可靠信號與不可靠信號,前32種信號為不可靠信號,后32種為可靠信號。

1.1 概念
  • 不可靠信號: 也稱(chēng)為非實(shí)時(shí)信號,不支持排隊,信號可能會(huì )丟失, 比如發(fā)送多次相同的信號, 進(jìn)程只能收到一次. 信號值取值區間為1~31;

  • 可靠信號: 也稱(chēng)為實(shí)時(shí)信號,支持排隊, 信號不會(huì )丟失, 發(fā)多少次, 就可以收到多少次. 信號值取值區間為32~64

1.2 信號表

在終端,可通過(guò)kill -l查看所有的signal信號

取值名稱(chēng)解釋默認動(dòng)作
1SIGHUP掛起
2SIGINT中斷
3SIGQUIT退出
4SIGILL非法指令
5SIGTRAP斷點(diǎn)或陷阱指令
6SIGABRTabort發(fā)出的信號
7SIGBUS非法內存訪(fǎng)問(wèn)
8SIGFPE浮點(diǎn)異常
9SIGKILLkill信號不能被忽略、處理和阻塞
10SIGUSR1用戶(hù)信號1
11SIGSEGV無(wú)效內存訪(fǎng)問(wèn)
12SIGUSR2用戶(hù)信號2
13SIGPIPE管道破損,沒(méi)有讀端的管道寫(xiě)數據
14SIGALRMalarm發(fā)出的信號
15SIGTERM終止信號
16SIGSTKFLT棧溢出
17SIGCHLD子進(jìn)程退出默認忽略
18SIGCONT進(jìn)程繼續
19SIGSTOP進(jìn)程停止不能被忽略、處理和阻塞
20SIGTSTP進(jìn)程停止
21SIGTTIN進(jìn)程停止,后臺進(jìn)程從終端讀數據時(shí)
22SIGTTOU進(jìn)程停止,后臺進(jìn)程想終端寫(xiě)數據時(shí)
23SIGURGI/O有緊急數據到達當前進(jìn)程默認忽略
24SIGXCPU進(jìn)程的CPU時(shí)間片到期
25SIGXFSZ文件大小的超出上限
26SIGVTALRM虛擬時(shí)鐘超時(shí)
27SIGPROFprofile時(shí)鐘超時(shí)
28SIGWINCH窗口大小改變默認忽略
29SIGIOI/O相關(guān)
30SIGPWR關(guān)機默認忽略
31SIGSYS系統調用異常

對于signal信號,絕大部分的默認處理都是終止進(jìn)程或停止進(jìn)程,或dump內核映像轉儲。 上述的31的信號為非實(shí)時(shí)信號,其他的信號32-64 都是實(shí)時(shí)信號。

二、信號產(chǎn)生

信號來(lái)源分為硬件類(lèi)和軟件類(lèi):

2.1 硬件方式
  • 用戶(hù)輸入:比如在終端上按下組合鍵ctrl+C,產(chǎn)生SIGINT信號;

  • 硬件異常:CPU檢測到內存非法訪(fǎng)問(wèn)等異常,通知內核生成相應信號,并發(fā)送給發(fā)生事件的進(jìn)程;

2.2 軟件方式

通過(guò)系統調用,發(fā)送signal信號:kill(),raise(),sigqueue(),alarm(),setitimer(),abort()

  • kernel,使用 kill_proc_info()等

  • native,使用 kill() 或者raise()等

  • java,使用 Procees.sendSignal()等

三、信號注冊和注銷(xiāo)3.1 注冊

在進(jìn)程task_struct結構體中有一個(gè)未決信號的成員變量 struct sigpending pending。每個(gè)信號在進(jìn)程中注冊都會(huì )把信號值加入到進(jìn)程的未決信號集。

  • 非實(shí)時(shí)信號發(fā)送給進(jìn)程時(shí),如果該信息已經(jīng)在進(jìn)程中注冊過(guò),不會(huì )再次注冊,故信號會(huì )丟失;

  • 實(shí)時(shí)信號發(fā)送給進(jìn)程時(shí),不管該信號是否在進(jìn)程中注冊過(guò),都會(huì )再次注冊。故信號不會(huì )丟失;

3.2 注銷(xiāo)
  • 非實(shí)時(shí)信號:不可重復注冊,最多只有一個(gè)sigqueue結構;當該結構被釋放后,把該信號從進(jìn)程未決信號集中刪除,則信號注銷(xiāo)完畢;

  • 實(shí)時(shí)信號:可重復注冊,可能存在多個(gè)sigqueue結構;當該信號的所有sigqueue處理完畢后,把該信號從進(jìn)程未決信號集中刪除,則信號注銷(xiāo)完畢;

四、信號處理

內核處理進(jìn)程收到的signal是在當前進(jìn)程的上下文,故進(jìn)程必須是Running狀態(tài)。當進(jìn)程喚醒或者調度后獲取CPU,則會(huì )從內核態(tài)轉到用戶(hù)態(tài)時(shí)檢測是否有signal等待處理,處理完,進(jìn)程會(huì )把相應的未決信號從鏈表中去掉。

4.1 處理時(shí)機

signal信號處理時(shí)機: 內核態(tài) -> signal信號處理 -> 用戶(hù)態(tài):

  • 在內核態(tài),signal信號不起作用;

  • 在用戶(hù)態(tài),signal所有未被屏蔽的信號都處理完畢;

  • 當屏蔽信號,取消屏蔽時(shí),會(huì )在下一次內核轉用戶(hù)態(tài)的過(guò)程中執行;

4.2 處理方式

進(jìn)程對信號的處理方式: 有3種

  • 默認 接收到信號后按默認的行為處理該信號。 這是多數應用采取的處理方式。

  • 自定義 用自定義的信號處理函數來(lái)執行特定的動(dòng)作

  • 忽略 接收到信號后不做任何反應。

4.3 信號安裝

進(jìn)程處理某個(gè)信號前,需要先在進(jìn)程中安裝此信號。安裝過(guò)程主要是建立信號值和進(jìn)程對相應信息值的動(dòng)作。

信號安裝函數

  • signal():不支持信號傳遞信息,主要用于非實(shí)時(shí)信號安裝;

  • sigaction():支持信號傳遞信息,可用于所有信號安裝;

其中 sigaction結構體

  • sa_handler:信號處理函數

  • sa_mask:指定信號處理程序執行過(guò)程中需要阻塞的信號;

  • sa_flags:標示位

    • SA_RESTART:使被信號打斷的syscall重新發(fā)起。

    • SA_NOCLDSTOP:使父進(jìn)程在它的子進(jìn)程暫?;蚶^續運行時(shí)不會(huì )收到 SIGCHLD 信號。

    • SA_NOCLDWAIT:使父進(jìn)程在它的子進(jìn)程退出時(shí)不會(huì )收到SIGCHLD信號,這時(shí)子進(jìn)程如果退出也不會(huì )成為僵 尸進(jìn)程。

    • SA_NODEFER:使對信號的屏蔽無(wú)效,即在信號處理函數執行期間仍能發(fā)出這個(gè)信號。

    • SA_RESETHAND:信號處理之后重新設置為默認的處理方式。

    • SA_SIGINFO:使用sa_sigaction成員而不是sa_handler作為信號處理函數。

函數原型:

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

  • signum:要操作的signal信號。

  • act:設置對signal信號的新處理方式。

  • oldact:原來(lái)對信號的處理方式。

  • 返回值:0 表示成功,-1 表示有錯誤發(fā)生。

4.4 信號發(fā)送
  • kill():用于向進(jìn)程或進(jìn)程組發(fā)送信號;

  • sigqueue():只能向一個(gè)進(jìn)程發(fā)送信號,不能像進(jìn)程組發(fā)送信號;主要針對實(shí)時(shí)信號提出,與sigaction()組合使用,當然也支持非實(shí)時(shí)信號的發(fā)送;

  • alarm():用于調用進(jìn)程指定時(shí)間后發(fā)出SIGALARM信號;

  • setitimer():設置定時(shí)器,計時(shí)達到后給進(jìn)程發(fā)送SIGALRM信號,功能比alarm更強大;

  • abort():向進(jìn)程發(fā)送SIGABORT信號,默認進(jìn)程會(huì )異常退出。

  • raise():用于向進(jìn)程自身發(fā)送信號;

4.5 信號相關(guān)函數

信號集操作函數

  • sigemptyset(sigset_t *set):信號集全部清0;

  • sigfillset(sigset_t *set): 信號集全部置1,則信號集包含linux支持的64種信號;

  • sigaddset(sigset_t *set, int signum):向信號集中加入signum信號;

  • sigdelset(sigset_t *set, int signum):向信號集中刪除signum信號;

  • sigismember(const sigset_t *set, int signum):判定信號signum是否存在信號集中。

信號阻塞函數

  • sigprocmask(int how, const sigset_t *set, sigset_t *oldset)); 不同how參數,實(shí)現不同功能

    • SIG_BLOCK:將set指向信號集中的信號,添加到進(jìn)程阻塞信號集;

    • SIG_UNBLOCK:將set指向信號集中的信號,從進(jìn)程阻塞信號集刪除;

    • SIG_SETMASK:將set指向信號集中的信號,設置成進(jìn)程阻塞信號集;

  • sigpending(sigset_t *set)):獲取已發(fā)送到進(jìn)程,卻被阻塞的所有信號;

  • sigsuspend(const sigset_t *mask)):用mask代替進(jìn)程的原有掩碼,并暫停進(jìn)程執行,直到收到信號再恢復原有掩碼并繼續執行進(jìn)程。

Linux信號(signal)機制 - JackPeng博客 (yuanfentiank789.github.io)

*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。



關(guān)鍵詞: linux

相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>