GLib 實現了一個功能強大的事件循環分發處理機制,被抽象成為 GMainLoop,用于循環處理事件源上的事件。每個 GMainLoop 都工作在指定的 GMainContext 上。事件源在 GLib 中則被抽象成了 GSource。在 GMainContext 中有一個 GSource 列表。GLib 內部定義實現了三種類型的事件源,分別是 Idle, Timeout 和 I/O。同時也支持創建自定義的事件源。
自定義事件源的基本作用
自定義的事件源可以用來將外部信號(事件)掛到程序中的指定主循環上,從而在 g_main_loop_run 中可以響應這些事件。
如何創建自定義事件源
GLib 提供了一系列的接口用于創建自定義的事件源,下面我們先講解一下創建事件源的基本函數和數據結構,最后給出一些實例。
自定義的事件源是一個繼承 GSource 的結構體,即自定義事件源的結構體 的第一個成員是 GSource 結構體, 其后便可放置程序所需數據,
實現了事件源數據結構的定義之后,還需要實現事件源所規定的接口,主要為 prepare, check, dispatch, finalize 等事件處理函數(回調函數),它們包含于 GSourceFuncs 結構體中。將 GSourceFuncs 結構以及事件源結構的存儲空間寬度作為參數傳給 g_source_new 便可構造一個新的事件源,繼而可使用 g_source_attach 函數將新的事件源添加到主循環上下文中。
Timeout 類事件源,GLib 也提供了預定義的定時器事件源,其用法與 GLib 預定義的空閑事件源類似。例如:
如果要自定義定時器類型的事件源,只需讓事件源的 prepare 與 check 接口在時間超過所設定的時間間隔時返回 TRUE, 否則返回 FALSE。
I/O 類型的事件源要稍微難理解一些,因為涉及到了操作系統層面的 poll 機制。所謂 poll 機制,就是操作系統提供的對文件描述符所關聯的 I/O 的狀態監視功能 ,例如向文件中寫入數據 ,那么 I/O 的狀態可以表示為 POLLOUT, 而從文件中讀取數據,那么 I/O 的狀態就變為 POLLIN。GLib 為 Unix 系統與Windows 系統的 poll 機制進行了封裝,并且可以將文件與主事件循環的事件源建立關聯,在主循環的過程中, g_main_loop_run 會輪詢各個關聯到文件的事件源,并處理相應的事件響應。I/O 類型的事件源, prepare,其 check, dispatch 等接口的執行次序如下:
a. 主事件循環會首先調用 check 接口, 詢問事件源是否準備好。因為此時, g_main_loop_run 尚未輪詢那些與 I/O 相關聯的事件源, 所以 I/O 類型的事件源, check 接口的返回值應該是 FALSE。其主事件循環調用 g_main_context_iteration 輪詢各事件源,探尋是否有 I/O 類型事件源的狀態發生變化,并記錄變化結果。
b. 主循環調用 check 接口, 詢問事件是否準備好。此時, 如果 I/O 類型事件源的狀態變化符合要求,那么就返回 TRUEE,否則返回 FALSE。
c. 如果 prepare 與 check接口的返回值均為 TRUE, 那么此時主事件循環會調用 dispatch 接口分發消息。
像 Idle 類型與 Timeout 類型事件源那樣,GLib 也提供了預定義的 I/O 類型事件源,
-
Glibc
+關注
關注
0文章
9瀏覽量
7519
發布評論請先 登錄
相關推薦
評論