Process

是什麼導致各種信號被發送?

  • February 28, 2022

我有時會對程序可以接收的所有信號感到有些困惑。據我了解,一個程序對這些信號中的每一個都有一個預設處理程序(信號處置),但它可以通過呼叫提供自己的處理程序sigaction()

所以這是我的問題:是什麼導致每個信號被發送?我意識到您可以通過-s參數 to手動向正在執行的程序發送信號kill,但是發送這些信號的*自然情況是什麼?*例如,什麼時候SIGINT發送?

另外,對可以處理哪些信號有任何限制嗎?甚至SIGSEGV可以處理信號並將控制權返回給應用程序嗎?

除了程序呼叫之外,核心(或有時由程序本身)在各種情況下發送kill(2)一些信號:

  • 終端驅動程序發送對應各種事件的信號:

    • 按鍵通知:( SIGINT請返回主循環)在Ctrl+上CSIGQUIT(請立即退出)在Ctrl+上\SIGTSTP(請暫停)在Ctrl+上Z。可以使用stty命令更改鍵。
    • SIGTTINSIGTTOU在後台程序嘗試讀取或寫入其控制終端時發送。
    • SIGWINCH發送以表示終端視窗的大小已更改。
    • SIGHUP發送信號以表明終端已消失(過去是因為您的調製解調器已掛起**,****現在**通常是因為您關閉了終端仿真器視窗)。
  • 一些處理器陷阱可以生成信號。細節取決於架構和系統;以下是典型的例子:

    • SIGBUS對於未對齊的存取儲存器;
    • SIGSEGV訪問未映射的頁面;
    • SIGILL對於非法指令(錯誤的操作碼);
    • SIGFPE對於帶有錯誤參數的浮點指令(例如sqrt(-1))。
  • 許多信號通知目標程序發生了一些系統事件:

    • SIGALRM通知程序設置的計時器已過期。定時器可以用alarm,setitimer和其他來設置。
    • SIGCHLD通知一個程序它的一個孩子已經死亡。
    • SIGPIPE當讀取端已關閉時程序嘗試寫入管道時生成(其想法是,如果您執行foo | barbar退出,則會foo被 a 殺死SIGPIPE)。
    • SIGPOLL(也稱為SIGIO)通知程序發生了可輪詢事件。POSIX 指定通過I_SETSIG ioctl. O_ASYNC fcntl許多系統允許通過標誌設置的任何文件描述符上的可輪詢事件。一個相關的信號是SIGURG,它通知設備(通過 註冊I_SETSIG ioctl)或套接字上的緊急數據。
    • 在某些系統上,當UPS發出即將發生電源故障的信號時,SIGPWR它會發送到所有程序。

這些列表並不詳盡。標准信號定義在signal.h.

大多數信號都可以被應用程序擷取和處理(或忽略)。僅有的兩個不能被擷取的攜帶式信號是SIGKILL(just die)和STOP(stop execution)。

SIGSEGV分段錯誤)及其表親SIGBUS匯流排錯誤)可以被擷取,但這是一個壞主意,除非你真的知道你在做什麼。擷取它們的常見應用程序是列印堆棧跟踪或其他調試資訊。更高級的應用是實現某種程序內記憶體管理,或者在虛擬機引擎中擷取錯誤指令。

最後,讓我提一些不是信號的東西。當您在從終端讀取輸入的程序的行首按Ctrl+時,這會告訴程序已到達輸入文件的末尾。D這不是信號:它是通過輸入/輸出 API 傳輸的。像Ctrl+C和朋友一樣,鍵可以配置為stty

引用自:https://unix.stackexchange.com/questions/6332