Unix系統的行程間通訊機制中,有一套稱為 signal 的信號機制。因為它被列在 POSIX 規範之中,所以本文將以 Posix signal 稱之。Psoxi signal 是一種簡單的事件通知機制。它將某些事件予以編號,例如 SIGHUP, SIGTERM 等。程序可以向系統註冊這些信號的處理函式。當特定事件發生時,系統就會打斷程序目前的流程,將執行點轉移到程序指定的處理函式。
然而從設計模式的眼光來看,Posix signal 對程序而言是 Singalton 模式,它只有一個實體。所以同一時間,每一個 Posix 信號只能註冊一個處理函式。當你的程序內有多個單元關心同一個 Posix 信號時,程序員必須要另行安排登記與分派機制,以免不同的單元彼此爭搶 Posix 信號的處理權。 GNOME 環境的程序員,可以利用 GObject 型別機制提供的 GObject signal 機制,實現 Posix signal 的分派機制。
注意,GNOME 核心的 GObject 型別機制,也提供了一套基於個體的 signal 機制。雖然都叫 signal,但 GObject signal 與 Posix signal 兩者的內容完全不同。
實作說明
由於 Posix signal 係由作業系統提供,故我在此稱為 System Signal。我先以 Singalton 設計模式撰寫一個專責接收 Posix signal 的 Handler 類別,其內有一個基於 GObject 的實體。當 Handler 接收到 Posix signal 之後,會再透過 GObject signal 機制轉發給其他人。因此外部可同樣透過 GObject signal 去傾聽 Posix signal 。由 GObject signal 機制去負責 Posix signal 的再分派工作。
SystemSignal.Handler 提供類別方法 singalton() 讓外部取得其單一實體。當此實體接受到 Posix signal 時,則會發送名為 delivered 的 GObject signal,其夾帶的參數 signum 則為此次接受到的 Posix signal 代號。
SignalAgent 則實作了一個會其傾聽 SystemSignal.Handler 所發送的信號的類別。凡是對 Posix signal 有興趣的單元,都可以自己配置一個 SignalAgent 實體,並指派各自的處理函數。彼此獨立,不會發生爭搶 Posix signal 處理權的問題。