透過loop與monitor的方式來做事件的處理
觸發不同的事件來執行不同的 callback
Libev 官方網站
這算是我工作上第一個遇到的新工具~
一開始看官方文件 還是霧煞煞~
不過 實際去RUN個幾次 你就會懂他的 邏輯與方式了~
這次要回頭處理 原本的ev 事件程式
想測試看看用 multi thread 來提升 處理效能
使用libev 如果希望工頭(主程序)隨時身邊都有工人(thread)待命,一有事情就派工人處理
但要讓工人處於待命狀態,而且又要聽命於工頭
其中 ev_async 是很重要的一個"秘書",可以幫忙與其他工人溝通
ev_async async_watcher;
ev_loop thread_loop;
ev_io main_event;
EV_P;
int main()
{
loop = ev_default_loop(0);
thread_loop= ev_loop_new(0);
pthread_t thread;
ev_async_init(async_watcher, async_cb);
ev_async_start(thread_loop ,async_watcher);
pthread_create(&thread, NULL, pthread_function, NULL);
ev_io_init(&main_event, cb_main_callback, fd, EV_READ);
ev_run(EV_A_ 0);
}
void *pthread_function(void *ptr)
{
ev_run(thread_loop, 0);
pthread_exit(0);
return NULL;
}
void cb_main_callback(EV_P_ ev_io *w, int revents)
{
if(ev_async_pending(&mthread[thread_count].async_watcher) == 0)
{
async_watcher.data = (void *)"Test Multi Thread";
ev_async_send(thread_loop , &async_watcher);
}
}
void async_cb(EV_P_ ev_async *w, int revents)
{
char * msg;
msg = (char *)w->data
printf("%s\n",msg);
}
擷取程式中 部分程式碼說明一下 ev_async的 運作流程首先主程序 在執行 ev_run(EV_A_ 0); 之前
註冊了一個 async_watcher 並指定 callback async_cb()
並啟 ev_async_start(thread_loop ,async_watcher);
在pthread_create() 的時候讓 thread_loop 運作 此時因為
有註冊async_watcher 所以不會 thread_loop 直接結束掉
再來重點在於 主程序 進到 cb_main_callback() 中
ev_async_pending() 這個動作 要跟 ev_async_send()
一起講會比較清楚
在ev_async_send()在 thread_loop 做個標記 此時會可以讓loop
去進到async_cb() 而此時會把 ev_async_send()所做的標記重置
而 ev_async_pending() 到底有啥作用呢
有人可能從字面上覺得 是在看是否呈現等待狀態
但實際的運作是
當已經被ev_async_send()標記 但loop並未觸發,則會回傳非0的值
所以我們必須判斷 ev_async_pending()等於0
才能再進行一次 ev_async_send()
通常在使用會遇到一個問題 就是 我需要帶資料或變數改怎麼處理
可能比較常看到 是使用 全域的變數 使用 lock 的方式
而其實 ev 事件 的monitor的struct 都會有一些變數可以使用
可以很方便在不同的callback傳遞
struct ev_async {
sig_atomic_t volatile sent;
int active;
int pending;
int priority;
void* data;
void (*cb)(struct ev_loop *loop, struct ev_async *w, int revents);
};
更多範例 可以在搜尋關鍵字 "libev thread" , "ev_async"
下面連結是 網路上的範例 自己有稍微修改測試了一下~
參考連結
http://stackoverflow.com/questions/14621261/using-libev-with-multiple-threads