狠狠撸
Submit Search
給 GLib 使用者的 libev 簡介
?
5 likes
?
3,065 views
C
crabtw
Follow
1 of 16
Download now
Downloaded 40 times
More Related Content
給 GLib 使用者的 libev 簡介
1.
. .
給 GLib 使用者的 libev 簡介 April 17, 2013 . .. .. . . .. .. .. . . .. .. .. . . .. .. .. . . .. . . .. .. .
2.
Event Loop Library
? libev 是 event loop library,跟 GLib 的 main event loop 一樣 ? 支援多種 monitor 機制,如 select, poll, epoll, kqueue ? 但是只提供基本的功能,建議依需求再包一層 . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 2 / 16
3.
常用的 data type
? Event loop ? ev_loop 相當於 GMainContext 與 GMainLoop 的合體 ? Event watcher ? ev_io 相當於 GIOUnixWatch,但要自己處理 EINTR, EAGAIN ? ev_timer 相當於 GTimeoutSource,但時間單位是秒 ? ev_async 用於 thread 之間的溝通。跟 GLib 不同,libev 不能在 thread 控制另 一個 thread 的 ev_loop,要用 ev_async 去溝通 . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 3 / 16
4.
使用流程
建立 event loop int main(void) { struct ev_loop *loop = .ev_default_loop ( EVBACKEND_EPOLL ) ; struct ev_io stdin_w ; . ev_io_init (& stdin_w , stdin_cb , STDIN_FILENO , EV_READ ); . ev_io_start (loop , & stdin_w ); . ev_run (loop , 0); 初始化 watcher return 0; 註冊 watcher } 開始 event loop . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 4 / 16
5.
Callback function
註冊的 watcher,type 依 event 而定 void callback ( struct ev_loop *lo , . struct ev_watcher *w , . int revents ); . 收到的 event 的 type ? 如果要傳入 user data,可以繼承 watcher 的 structure 或是用 offsetof 計算 data 的位置 . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 5 / 16
6.
範例 ? 用 ev_timer
實作 GLib timeout ? 建一個 thread 專門處理 timeout event ? 使用 ev_async 與 GAsyncQueue 處理 thread 之間的溝通 . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 6 / 16
7.
Data types
繼承 ev_timer struct Timeout { . struct ev_timer watcher ; guint intval ; GSourceFunc func; gpointer data; GDestroyNotify dtor; }; 送給 timeout thread 的訊息 .struct Msg { enum { MSG_TYPE_ADD , MSG_TYPE_REMOVE , MSG_TYPE_CLEANUP } type; struct Timeout * timeout ; }; . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 7 / 16
8.
Initialization static ev_loop *loop; static
GAsyncQueue * msg_queue ; static GThread * timeout_th ; void timeout_init (void) { msg_queue = g_async_queue_new (); timeout_th = g_thread_new (" timeout ", main_loop , NULL ); } . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 8 / 16
9.
Timeout thread
event loop 使用 epoll static gpointer main_loop ( gpointer _) { . loop = ev_loop_new ( EVBACKEND_EPOLL ); . ev_async_init (& msg_watcher , msg_handler ); . ev_async_start (loop , & msg_watcher ); . ev_run (loop , 0); 註冊 watcher 處理 thread 之間的溝通 ev_loop_destroy (loop ); return NULL; } 開始 event loop . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 9 / 16
10.
接收及處理訊息 static void msg_handler
( struct ev_loop *lo , struct ev_async *w, int ev) { struct Msg *m; while ((m = g_async_queue_try_pop ( msg_queue ))) { struct Timeout *t = m-> timeout ; // handle message g_free (m); } } . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 10 / 16
11.
處理訊息 // handle message switch
(m->type) { case MSG_TYPE_ADD : . ev_timer_init (&t->watcher , timeout_cb , . 0., t-> intval / 1000.); . ev_timer_again (lo , &t-> watcher ); break ; 開始新的 timer case MSG_TYPE_REMOVE : . ev_timer_stop (lo , &t-> watcher ); if (t->dtor) { t->dtor(t->data ); 停止 timer } g_free (t); break ; case MSG_TYPE_CLEANUP : . ev_break (lo , EVBREAK_ALL ); break ; 停止 event loop } . .. . .. . .. . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. . .. . .. . .. . .. . 給 GLib 使用者的 libev 簡介 April 17, 2013 11 / 16
12.
Callback wrapper static void
timeout_cb ( struct ev_loop *lo , struct ev_timer *w, int ev) { struct Timeout *t = ( struct Timeout *)w; if (t->func(t->data )) { . ev_timer_again (lo , w); } else { timeout_remove (t); 繼續執行 timer } } . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 12 / 16
13.
Timeout add struct Timeout
* timeout_add ( guint intval , GSourceFunc func , gpointer data , GDestroyNotify dtor) { struct Timeout *t = g_malloc0 ( sizeof (*t)); t-> intval = intval ; t->func = func; t->data = data; t->dtor = dtor; struct Msg *m = g_malloc0 ( sizeof (*m)); m->type = MSG_TYPE_ADD ; m-> timeout = t; 通知 timeout thread . g_async_queue_push (msg_queue , m); . ev_async_send (loop , & msg_watcher ); return t; } . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 13 / 16
14.
Timeout remove void timeout_remove
( struct Timeout *t) { struct Msg *m = g_malloc0 ( sizeof (*m)); m->type = MSG_TYPE_REMOVE ; m-> timeout = t; 通知 timeout thread . g_async_queue_push (msg_queue , m); . ev_async_send (loop , & msg_watcher ); } . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 14 / 16
15.
Cleanup void timeout_cleanup (void)
{ struct Msg *m = g_malloc0 ( sizeof (*m)); m->type = MSG_TYPE_CLEANUP ; 通知 timeout thread . g_async_queue_push (msg_queue , m); . ev_async_send (loop , & msg_watcher ); g_thread_join ( timeout_th ); g_async_queue_unref ( msg_queue ); } . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 15 / 16
16.
使用 timeout static gboolean
timeout ( GMainLoop *loop) { return ! g_main_loop_is_running (loop ); } int main(void) { . timeout_init (); GMainLoop *loop = g_main_loop_new (NULL , FALSE ); . struct Timeout *t = timeout_add ( . 1000 , ( GSourceFunc )timeout , . loop , ( GDestroyNotify ) g_main_loop_quit . ); g_main_loop_run (loop ); . timeout_cleanup (); return 0; } . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 給 GLib 使用者的 libev 簡介 April 17, 2013 16 / 16
Download