行程間通訊

信號(signal)

想像你正全神貫注地寫報告,有人拍了拍你的肩膀。你停下手邊的事、處理這一拍,再回去寫。信號就是行程的這一記拍肩。它是一個微小、非同步的通知——「非同步」意思是它可能在任何時刻、在任意兩條機器指令之間到達,而不是在你程式碼選定的某個點。行程被打斷,一個信號被遞送,然後它繼續(或者對某些信號來說,它不再繼續)。

信號幾乎不攜帶任何東西——只有一個標明它是哪個信號的編號。沒有資料負載;意義完全在那個編號裡,而每個編號都有個名字,像 SIGINT 或 SIGTERM。由核心負責遞送。有些信號來自核心本身對你程式行為的反應(碰到無效位址,核心就送 SIGSEGV);有些來自終端機(按 Ctrl-C 會送 SIGINT 給前景程式);有些則是另一個行程刻意送的,或是你在命令列用 kill 送的。信號到達時,行程依該信號的處置方式(disposition)做三件事之一:執行你安裝的處理常式、忽略它,或採取預設動作(對許多信號而言是終止)。

信號是 IPC 中典型的「信號通知」方式:一個不帶內容的輕推,說「發生了某件事,去處理」。它們無所不在——Ctrl-C、父行程得知子行程結束了(SIGCHLD)、行程被要求乾淨地關閉(SIGTERM)或被直接殺掉(SIGKILL)。必須尊重的一點是它的非同步性:因為信號真的可能在任何地方打斷你的程式碼,回應它而執行的程式碼(信號處理常式)對它能安全碰觸什麼受到危險的限制——這個微妙之處在 async-signal-safety 中討論。

在終端機按 Ctrl-C:驅動程式把 SIGINT(信號編號 2)送給前景行程。若沒有處理常式,就執行預設動作、行程終止——這就是為什麼 Ctrl-C 能停掉一個失控的程式。

信號不過是一個突然到來的編號。它的名字承載意義;它的處置方式決定反應。

信號不是訊息:除了編號外不攜帶任何資料,而且相同的信號可能被合併(兩個 SIGCHLD 可能只遞送成一個)。把信號當作「有某個狀況待處理」,絕不要把它當成可靠的逐事件計數器。

又称
software interrupt to a process信號軟體信號