signal --- 設定非同步事件的處理函式¶
原始碼:Lib/signal.py
本模組提供於 Python 中使用訊號處理程式的機制。
一般規則¶
signal.signal() 函式允許定義自訂的處理程式,會在收到訊號時執行。我們安裝了少數的預設處理程式:SIGPIPE 會被忽略 (所以管道和 socket 上的寫入錯誤可以當作一般的 Python 例外報告),而 SIGINT(如果父行程沒有改變它的話)會被轉換成 KeyboardInterrupt 例外。
特定訊號的處理程式一旦被設定,就會一直被安裝,直到被明確地重設為止 (不管底層的實作為何,Python 皆模擬出 BSD 風格的介面),但 SIGCHLD 的處理程式除外,它會跟隨底層的實作。
在 WebAssembly 平台上,訊號是模擬出來的,故行為不同。有幾個函式和訊號在這些平台上是不可用的。
Python 訊號處理程式的執行¶
Python 訊號處理程式不會在低階(C 語言)訊號處理程式中執行。相反地,低階訊號處理程式會設定一個旗標,告訴虛擬機在稍後執行相對應的 Python 訊號處理程式(例如在下一個 bytecode 指令)。這會有一些後果:
捕捉像
SIGFPE或SIGSEGV這類由 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_DFL、SIG_IGN)和訊號遮罩 (sigmask)(SIG_BLOCK、SIG_UNBLOCK、SIG_SETMASK)的相關常數被轉換成 enums(Signals、Handlers 和 Sigmasks)。getsignal()、pthread_sigmask()、sigpending() 和 sigwait() 函式會回傳可被人類閱讀的枚舉作為 Signals 物件。
訊號模組定義了三個枚舉:
- class signal.Signals¶
SIG* 常數和 CTRL_* 常數的
enum.IntEnum集合。在 3.5 版被加入.
- class signal.Handlers¶
SIG_DFL和SIG_IGN常數的enum.IntEnum集合。在 3.5 版被加入.
- class signal.Sigmasks¶
SIG_BLOCK、SIG_UNBLOCK和SIG_SETMASK常數的enum.IntEnum集合。可用性: Unix.
更多資訊請見 sigprocmask(2) 與 pthread_sigmask(3) 線上手冊。
在 3.5 版被加入.
在 signal 模組中定義的變數有:
- signal.SIG_DFL¶
這是兩種標準訊號處理選項之一;它會簡單地執行訊號的預設功能。例如,在大多數系統上,
SIGQUIT的預設動作是轉儲 (dump) 核心並退出,而SIGCHLD的預設動作是直接忽略。
- signal.SIG_IGN¶
這是另一個標準的訊號處理程式,會直接忽略給定的訊號。
- signal.SIGBUS¶
匯流排錯誤(記憶體存取不良)。