signal --- 設定非同步事件的處理函式

原始碼:Lib/signal.py


本模組提供於 Python 中使用訊號處理程式的機制。

一般規則

signal.signal() 函式允許定義自訂的處理程式,會在收到訊號時執行。我們安裝了少數的預設處理程式:SIGPIPE 會被忽略 (所以管道和 socket 上的寫入錯誤可以當作一般的 Python 例外報告),而 SIGINT(如果父行程沒有改變它的話)會被轉換成 KeyboardInterrupt 例外。

特定訊號的處理程式一旦被設定,就會一直被安裝,直到被明確地重設為止 (不管底層的實作為何,Python 皆模擬出 BSD 風格的介面),但 SIGCHLD 的處理程式除外,它會跟隨底層的實作。

在 WebAssembly 平台上,訊號是模擬出來的,故行為不同。有幾個函式和訊號在這些平台上是不可用的。

Python 訊號處理程式的執行

Python 訊號處理程式不會在低階(C 語言)訊號處理程式中執行。相反地,低階訊號處理程式會設定一個旗標,告訴虛擬機在稍後執行相對應的 Python 訊號處理程式(例如在下一個 bytecode 指令)。這會有一些後果:

  • 捕捉像 SIGFPESIGSEGV 這類由 C 程式碼中無效操作所引起的同步錯誤是沒有意義的。Python 將從訊號處理程式中回傳到 C 程式碼,而 C 程式碼很可能再次引發相同的訊號,導致 Python 明顯假當機 (hang)。從 Python 3.3 開始,你可以使用 faulthandler 模組來報告同步錯誤。

  • 純粹以 C 實作的長時間計算(例如在大量文字上的正規表示式比對)可能會不間斷地運行任意長度的時間而不考慮收到的任何訊號。當計算完成時,Python 訊號處理程式會被呼叫。

  • 如果處理程式引發例外,就會在主執行緒中「憑空」產生例外。請參閱下面的說明

訊號和執行緒

Python 訊號處理程式總是在主直譯器的主 Python 執行緒中執行,即使訊號是在另一個執行緒中接收到的。這意味著訊號不能用來做為執行緒間通訊的方式。你可以使用 threading 模組的同步原語 (synchronization primitive) 來代替。

此外,只有主直譯器的主執行緒才被允許設定新的訊號處理程式。

警告

Synchronization primitives such as threading.Lock should not be used within signal handlers. Doing so can lead to unexpected deadlocks.

模組內容

在 3.5 版的變更: 下面列出的訊號 (SIG*)、處理器(SIG_DFLSIG_IGN)和訊號遮罩 (sigmask)(SIG_BLOCKSIG_UNBLOCKSIG_SETMASK)的相關常數被轉換成 enumsSignalsHandlersSigmasks)。getsignal()pthread_sigmask()sigpending()sigwait() 函式會回傳可被人類閱讀的枚舉作為 Signals 物件。

訊號模組定義了三個枚舉:

class signal.Signals

SIG* 常數和 CTRL_* 常數的 enum.IntEnum 集合。

在 3.5 版被加入.

class signal.Handlers

SIG_DFLSIG_IGN 常數的 enum.IntEnum 集合。

在 3.5 版被加入.

class signal.Sigmasks

SIG_BLOCKSIG_UNBLOCKSIG_SETMASK 常數的 enum.IntEnum 集合。

可用性: Unix.

更多資訊請見 sigprocmask(2)pthread_sigmask(3) 線上手冊。

在 3.5 版被加入.

signal 模組中定義的變數有:

signal.SIG_DFL

這是兩種標準訊號處理選項之一;它會簡單地執行訊號的預設功能。例如,在大多數系統上,SIGQUIT 的預設動作是轉儲 (dump) 核心並退出,而 SIGCHLD 的預設動作是直接忽略。

signal.SIG_IGN

這是另一個標準的訊號處理程式,會直接忽略給定的訊號。

signal.SIGABRT

來自 abort(3) 的中止訊號。

signal.SIGALRM

來自 alarm(2) 的計時器訊號。

可用性: Unix.

signal.SIGBREAK

從鍵盤中斷 (CTRL + BREAK)。

可用性: Windows.

signal.SIGBUS

匯流排錯誤(記憶體存取不良)。