【Linux/Unix系統(tǒng)編程手冊筆記】信號

基本概念

概述

信號是事件發(fā)生時對進程的通知機制,有時也稱為軟件中斷,信號與硬件中斷相似之處在于打斷了程序執(zhí)行的正常流程,大多數(shù)情況下,無法預測信號到達的精確時間。
一個具有合適權(quán)限的進程能夠向另一進程發(fā)送信號,信號的這一用法可作為一種同步技術(shù),甚至是進程通信IPC的原始形式。進程也可以向自身發(fā)送信號。然而發(fā)生進程的諸多信號,通常都是源于內(nèi)核。

引發(fā)內(nèi)核為進程產(chǎn)生信號的各類事件如下:

  • 硬件發(fā)生異常:例子包括執(zhí)行一條異常的機器語言指令,如被0除,或者引用了無法訪問的內(nèi)存區(qū)域
  • 用戶鍵入能夠產(chǎn)生信號的中斷特殊字符:包括中斷字符(Control-C)
  • 發(fā)生了軟件事件:列入,針對文件描述符的輸出變?yōu)橛行?,調(diào)整了中斷窗口大小、定時器到期、進程執(zhí)行的CPU時間超限、或者改進程的某個子進程退出

信號分兩大類:

  • 內(nèi)核向進程通知事件,構(gòu)成所謂傳統(tǒng)或者標準信號,編號1~31
  • 實時信號

信號產(chǎn)生后,會稍后被傳遞給某一進行,而進程也會采取某些措施來響應(yīng)信號,在產(chǎn)生和到達期間,信號處于等待狀態(tài)。如果需要確保一段代碼不為傳遞來的信號所中斷,可將信號添加到信號掩碼中,會阻止該信號的到達,直到稍后對其解除阻塞。

信號到達后,進程視具體信號執(zhí)行如下默認操作之一:

  • 忽略信號:內(nèi)核將信號丟失
  • 終止進程
  • 產(chǎn)生核心轉(zhuǎn)儲文件,同時進程終止:核心轉(zhuǎn)儲文件包含對進程虛擬內(nèi)存的鏡像,可將其加載到調(diào)試器中以檢查進程終止時的狀態(tài)
  • 停止進程:暫停進程的執(zhí)行
  • 于之前暫停后再度恢復進程的執(zhí)行

程序能改變信號到達時的響應(yīng)行為,稱為對信號的處置設(shè)置:

  • 采取默認行為
  • 忽略信號
  • 執(zhí)行信號處理器(信號處理器程序是由程序員編寫的函數(shù),用于為響應(yīng)傳遞來的信號而執(zhí)行適當任務(wù))

信號類型和默認行為

Linux標準信號如下:

  • SIGABRT:進程調(diào)用abort()函數(shù)時,系統(tǒng)向進程發(fā)送該信號,默認情況下,該信號會終止進程,并產(chǎn)生核心轉(zhuǎn)儲文件,用于調(diào)試
  • SIGALRM:經(jīng)調(diào)用alarm()或setitimer()而設(shè)置的實時定時器一旦到期,內(nèi)核將產(chǎn)生該信號。實時定時器是根據(jù)掛鐘時間進行計時的
  • SIGBUS:(bus error)表示發(fā)生了某種內(nèi)存訪問錯誤
  • SIGCHLD:當父進程的某一子進程終止時(調(diào)用exit()或被信號殺死),內(nèi)核將向父進程發(fā)送該信號,當父進程的某一子進程因收到信號而停止或恢復時,也可能會向父進程發(fā)送該信號
  • SIGCLD:同SIGCHLD
  • SIGCONT:將該信號發(fā)送給已停止的進程,進程將會恢復運行
  • SIGEMT:UNIX系統(tǒng)通常用該信號標識一個依賴于實現(xiàn)的硬件錯誤
  • SIGFPE:該信號因特定類型的算術(shù)錯誤而產(chǎn)生,比如除0,后綴FPE是浮點異常的縮寫。
  • SIGHUP:當終端斷開(掛機)時,將發(fā)送該信號給終端控制進程。
  • SIGILL:執(zhí)行非法的機器語言指令
  • SIFINFO:鍵入Control—T產(chǎn)生SIFINFO信號,用于獲取前臺進程組的狀態(tài)信息
  • SIGINT:鍵入Control-C
  • SIGIO:利用fcntl()系統(tǒng)調(diào)用,即可與特點類型(終端和套接字)的打開文件描述符發(fā)生I/O事件時產(chǎn)生該信號
  • SIGIOT:與SIGABRT同義
  • SIGKILL:必殺信號,處理器程序無法將其阻塞
  • SIGLOST
  • SIGPIPE
  • SIGPOLL
  • SIGPROF
  • SIGPWR:電源故障信號
  • SIGQUIT
  • SIGSEGC:這一信號非常常見,當應(yīng)用程序?qū)?nèi)存的引用無效時,就會產(chǎn)生該信號。可能出現(xiàn)的情況:
    • 要引用的頁不存在,該頁位于堆和棧之間的未映射區(qū)域
    • 進程試圖更新只讀內(nèi)存
    • 進程企圖在用戶態(tài)去訪問內(nèi)核的部分內(nèi)存
  • SIGSTKFLT
  • SIGSTOP:必停信號,處理器程序無法將其阻塞、忽略或捕獲
  • SIGSYS:程序發(fā)起的系統(tǒng)調(diào)用有誤
  • SIGTERM:終止進程的標準信號,也是kill和killall命令發(fā)送的默認信號
  • SIGTRAP:用來實現(xiàn)斷點調(diào)試功能以及strace(1)命令所執(zhí)行的跟蹤系統(tǒng)調(diào)用功能。
  • SIGTSTP:作業(yè)控制的停止信號
  • SIGTTIN
  • SIGTTOU
  • SIGUNUSED
  • SIGURG
  • SIGUSR1:該信號與SIGUSR2信號供程序員自定義使用,內(nèi)核絕不會為進程產(chǎn)生這些信號。進程可以使用這些信號來相互通知事件的發(fā)生,或是彼此同步
  • SIGVTALRM
  • SIGWINCH:終端窗口尺寸發(fā)生變化時
  • SIGXCPU:當進程的CPU時間超出對應(yīng)的資源限制
  • SIGXFSZ:如果進程視圖增大文件而突破對進程文件大小的資源限制
image

image

改變信號處置:signal()

void signal(int sig, void (*handler)(int))

信號處理器簡介

信號處理器程序(也稱為信號捕捉器)是當指定信號傳遞給進程時將會調(diào)用的一個函數(shù),調(diào)用信號處理器程序,可能會隨時打斷主程序流程,內(nèi)核代表進程來調(diào)用處理器程序,當處理器返回時,主程序會在處理器打斷的位置恢復執(zhí)行。

image

發(fā)送信號:kill()

與shell的kill命令類似,一個進程能夠使用kill()系統(tǒng)調(diào)用向另一進程發(fā)送信號

int kill(pid_t pid, int sig)

檢查進程的存在

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.操作系統(tǒng)的核心——內(nèi)核 管理和分配計算機資源(即CPU、RAM和設(shè)備)的核心層軟件。 Linux內(nèi)核可執(zhí)行文件...
    666真666閱讀 646評論 0 3
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,537評論 19 139
  • 又來到了一個老生常談的問題,應(yīng)用層軟件開發(fā)的程序員要不要了解和深入學習操作系統(tǒng)呢? 今天就這個問題開始,來談?wù)劜?..
    tangsl閱讀 4,317評論 0 23
  • 草地上生活了一群驢,它們過著無憂無慮的日子。 它們吃草、飲水、交配、奔跑、發(fā)呆,在陽光照耀的山坡上,盡情享受著美好...
    燈下鼠閱讀 574評論 7 7
  • ANR相關(guān)問題 1. 什么是ANR? Application Not Responding : 應(yīng)用程序無響應(yīng)如果...
    wayneinyz閱讀 132評論 0 0

友情鏈接更多精彩內(nèi)容