glib信號與系統信號一些理解

LINUX 也有一段時間了 , 一直用 gtk, 看到 glib 下面有 gsignal, linux 下面又有 signal 定義的信號回調之類的 , 看起來很像 , 但是又不怎麼像 , 感覺有點模糊這之間到底有何關係呢?花了時間看了一下稍微總結一下 :

1.               他們之間無必然聯繫 ,gsignal glib 自定義一套信號集合系統 , 所謂的這個系統是運行在用戶態 , 完全不會執行內核的上下文切換,而且你可以理解成 , 同步回調。而 signal 是內核支持的 64 種事件的系統調用 , 所謂系統調用則一旦發生會進入內核去查找相應需要發送的進程去通知他們進行回調註冊。

2.               爲什麼 signal 定義的叫事件 ,gsignal 定義的叫信號? 在這裏事件一般認爲是外部觸發的 , 能夠喚醒進程進行調度的 , 而信號則不具備這樣能力 , 只是內部回調實現的一個機制命名爲信號。這裏所說均特指 glib 中。在 glib mainloop 在循環監測事件,其實並不監測 signal ,因爲 signal 一旦 emit 將直接訪問全局 signal 鏈表查找匹配的回調直接調用了,而無機會進入 loop 循環。

3.               那所謂的異步監測事件是什麼,是 glib 本身提供對系統 signal 的封裝,就是說他支持外部事件隊列,就是監測一個 FD 上的 IO 操作之類,然後一旦 glib 本身捕獲到這個事件後,解析一下打包成標準的 gsignal 信號發送,異步是異步在捕獲外部事件這個層面,而不在 gsignal 的發送上。

4.               那到底 gsignal 發送和 signal 發送有什麼不一樣,其實實現過程就是原理大致相同,把信號放到隊列中,然後檢測是否可以發送,而後回調指定的回調。但是要區別的是 gsignal 運行在用戶空間,而 signal 運行在內核空間,雖然原理一樣,但是一旦回調註冊的回調函數,那就是完全不同的, gsignal 因爲在同一個進程下會直接知道地址進行調用,而 signal 不行只能通過中斷喚醒相應進程還要壓入參數等等進行回調。 Gsignal 使用二叉樹行進排列 signal 節點因爲 signalid 也是一個 int 數據依次遞增,使用二叉樹查找排序的消耗比較穩定一些。而 signal 應該並沒有用特殊的數據結構,它只是與進程緊密綁定,所有進程包含一個 signal 等相關結構體來標誌目前監控那些信號, block 了那些信號,還有其信號的回調是否默認或者 ignore 還是用戶調用等等等等狀態,而且普通的信號不能被多次 pending 就是說信號不能沒有調用就又生成了。

5.               說下 signal 發送過程,其實系統事件處理分爲兩步 generate delivery ,生成階段只是在內核相應的進程的 signal 的結構中標誌一下我有這個信號需要處理就跑路了,而發送階段一般在後面系統調用發送後內核會檢測進程裏面是否有信號準備完畢了可以滿足條件發送了?滿足了就進行中斷進入用戶空間調用。在這中間要射沒射的就是 pending 狀態,你只能搞完了才能來接活工作。 Rt 處理則不一樣,這個不在討論只列。而 gsignal 也有 pending 列表,這個什麼狀況原來不是說信號發送是同步的嗎?還需要嘛個鏈表緩存信息啊,實際情況是 pending 我認爲是由外部事件觸發引起的,因爲外部事件觸發後如果沒機會執行,只能消息片緩存在那邊,等到工作忙完了一看已經有好多事件在那邊了,怎麼辦?那就進行緩存按照優先級進行排隊。進入 loop 循環一個一個調用 pending 的裏面的事件進行處理。雖然 gsignal 也處理外部事件,我認爲其處理還有封裝自己的一些業務在裏面並不是說一來就直接回調了,得按照 gsignal 統一得設計來做,排隊,按優先級一個一個做。不忙那就另當別論。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章