Glib之主事件循環


最近看開源代碼一直碰到使用glib的問題,調查下使用原理。

main loop

GLib和GTK+應用的主事件循環管理着所有事件源。

GLib 實現了一個功能強大的事件循環分發處理機制,這些事件的來源有很多種比如文件描述符(文件、管道或套接字)或超時。

新類型的事件源可以通過g_source_attach()函數添加。

爲了讓多組獨立事件源能夠在不同的線程中被處理,每個事件源都會關聯一個GMainContext。

一個線程只能運行一個GMainContext,但是在其他線程中能夠對事件源進行添加和刪除操作。
每個事件源都被賦予了優先級。默認的優先級是G_PRIORITY_DEFAULT(0)。值越小優先級越高,優先級高的事件源優先處理。

Idle函數在沒有更高優先級的事件被處理的時候纔會執行。

GMainLoop數據類型代表了一個主事件循環。
通過g_main_loop_new()來創建GMainLoop對象。
在添加完初始事件源後執行g_main_loop_run(),主循環將持續不斷的檢查每個事件源產生的新事件,然後分發它們,直到處理來自某個事件源的事件的時候觸發了g_main_loop_quit()調用退出主循環爲止。


GMainLoop實例能夠被遞歸創建。在GTK+應用中經常使用這種方式來顯示模態對話框。注意如果一個事件源被添加到一個GMainContext,那麼它將被所有關聯這個GMainContext的主線程檢查和分發。
GTK+對這些函數做了些封裝,例如gtk_main、gtk_mian_quit和gtk_events_pending。

main loop使用實例:

loop = g_main_loop_new (NULL, TRUE);
g_main_loop_run (loop);

g_main_loop_new創建一個main loop對象,一個main loop對象只能被一個線程使用,但一個線程可以有多個main loop對象。

在GTK+應用中,一個線程使用多個main loop的主要用途是實現模態對話框,它在gtk_dialog_run函數裏創建一個新的main loop,通過該main loop分發消息,直到對話框關閉爲止。

g_main_loop_run則是進入主循環,它會一直阻塞在這裏,直到讓它退出爲止。有事件時,它就處理事件,沒事件時就睡眠。

g_main_loop_quit則是用於退出主循環。

Glib main loop的最大特點就是支持多事件源,使用非常方便。來自用戶的鍵盤和鼠標事件、來自系統的定時事件和socket事件等等,還支持一個稱爲idle的事件源,其主要用途是實現異步事件。


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