Libev 官方文檔學習筆記 - 02:watcher 基礎

請注意這是 libev 而不是 libevent 的文章!segmentfault

這篇文章是第二篇,主要講 libev 裏的 watcher 的一些基礎操做。服務器

本文地址:http://www.javashuo.com/article/p-erndlmxa-ch.html異步

Watcher 解析

如下是一段示意性的代碼,使用的是ev_io函數

static void my_cb (struct ev_loop *loop, ev_io *w, int revents)
{
    ev_io_stop (w);
    ev_break (loop, EVBREAK_ALL);
}

some_main()
{
    ...
    
    struct ev_loop *loop = ev_default_loop (0);
    ev_io stdin_watcher;
    
    ev_init (&stdin_watcher, my_cb);
    ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ);
    ev_io_start (loop, &stdin_watcher);
    ev_run (loop, 0);
    
    ...
}

每個 watcher 類型有一個附屬的 watcher 結構體。(通常是struct ev_XXXev_XXX
  每個 watcher 結構都須要用ev_init初始化,每個 watcher 都有對應的ev_XXX_set函數、ev_XXX_start函數、ev_XXX_stop函數。在 ev_run 以前進行各個 watcher 的 ev_start。
  只要 watcher 是 active,就不能再調用 init。
  每一個 callback 都有三個參數:loop, watcher, 事件的掩碼值。可能的掩碼值有:oop

  • EV_READ
  • EV_WRITE
  • EV_TIMER:ev_timer 超時
  • EV_PERIODIC:ev_periodic 超時
  • EV_SIGNAL:某線程接收了 ev_signal 中指定的 signal
  • EV_CHILD:ev_child 中指定的 pid 得到了一個狀態變化
  • EV_STAT:ev_stat 中指定的 path 的屬性修改了
  • EV_IDLE:ev_idle watcher 發現無事可作
  • EV_PREPARE, EV_CHECK:全部 ev_prepare watchers 在 loop 開始收集事件前調用;全部ev_check watchers 則在之後調用。回調可在這兩個 watchers 中開始/中止相應的 watchers。
  • EV_EMBED:ev_embed watcher
  • EV_CLEANUP:event loop 即將被銷燬
  • EV_ASYNC:asuny watcher 已經被異步通知
  • EV_CUSTOM:不是 libev 發送的信號。參見ev_feed_event
  • EV_ERROR:在 libev 內存不夠用時可能產生;fd 被外部關閉時也可能產生

通用 watcher 函數

void ev_init (ev_TYPE *watcher, callback)

使用這個宏初始化 watcher。此外還須要調用相應的 ev_XXX_set 函數。參見下文:學習

void ev_TYPE_set (ev_TYPE *watcher, [args])

設置指定類型的 wetaher。init 函數必須在此以前被調用一次,此後能夠設置任意次的 set 函數。
  不能對一個 active 的 watcher 調用此函數,但 pending 能夠。好比:
ev_io w;
ev_init (&w, my_cb);
ev_io_set (&w, STDIN_FILENO, EV_READ);線程

void ev_TYPE_set (ev_TYPE *watcher, callback, [args])

這個宏將 init 和 set 糅合在一塊兒使用指針

void ev_TYPE_start (loop, ev_TYPE *watcher)

開始(激活)指定的 watcher。若是 watcher 已是 active,則調用無效。code

void ev_TYPE_stop (loop, ev_TYPE *watcher)

中止 watcher,並清空 pending 狀態。若是要釋放一個 Watcher,最好都顯式地調用 stop。接口

bool ev_is_active (ev_TYPE *watcher)

若是 watcher 被執行了一次 start,而且未被 stop,則返回 true。

bool ev_is_pending (ev_TYPE *watcher)

當且僅當 watcher pending 時返回 true。(如:有未決的事件,可是 callback 未被調用)

callback ev_cb (ev_TYPE *watcher)
void ev_set_cb (ev_TYPE *watcher, callback)

讀 / 寫 callback

void ev_set_priority (ev_TYPE *watcher, int priority)
int ev_priority (ev_TYPE *watcher)

Priority 是一個介於EV_MAXPRI(默認2)和EV_MIN_PRI(默認-2)之間的值。數值越高越優先被調用。但除了 ev_idle,每個 watcher 都會被調用。
  當 watcher 是 active 或 pending 時並不能修改。
  實際上 priority 大於-2到2的範圍也是沒問題的。

void ev_invoke (loop, ev_TYPE *watcher, int revents);

使用指定的參數調用 callback

int ev_clear_pending (loop, ev_TYPE *watcher);

清除指定 watcher 的 pending 狀態,而且返回 revents 位。若是 watcher 不是 pending 則返回0

void ev_feed_event (loop, ev_TYPE *watcher, int revents)

模擬一個事件。參見ev_feed_fd_eventev_feed_signal_event

Watcher 狀態

除了前文說起的 active 和 pending 狀態以外,本小節描述了更加詳細的 watcher 狀態。
  initialized:經過調用ev_TYPE_init對 watcher 進行初始化,這是註冊到 loop 以前的必要步驟。能夠再次調用 ev_TYPE_init 進行操做。
  started/running/active:調用ev_TYPE_start以後的狀態,而且開始等待事件。在這個狀態下,除了特別說起的少數狀況以外,它不能存取、移動、釋放,只能維持着對它的指針。
  pending:當 watcher 是 active 而且一個讓 watcher 感興趣的事件到來,那麼 watcher 進入 pending。這個狀態的 watcher 能夠 access,但不能存取、移動、釋放。
  stopped:調用ev_TYPE_stop,此時狀態與 initialized 相同。

系列篇

Libev 官方文檔學習筆記(1)——概述和 ev_loop
Libev 官方文檔學習筆記(2)——watcher 基礎(本文)
Libev 官方文檔學習筆記(3)——經常使用 watcher 接口
使用 libev 構建 TCP 響應服務器的簡單流程

相關文章
相關標籤/搜索