libuv之async使用

来源:互联网 发布:淘宝买东西怎么要发票 编辑:程序博客网 时间:2024/04/29 02:54

libuv中async的使用比较难理解一些,我们来一起学习下

简介

vu_async_t是我们要用的handle,这个handle用来在线程间通信的。我们看一下官方的解释
/* * uv_async_t is a subclass of uv_handle_t. * * uv_async_send wakes up the event loop and calls the async handle's callback. * There is no guarantee that every uv_async_send call leads to exactly one * invocation of the callback; the only guarantee is that the callback function * is called at least once after the call to async_send. Unlike all other * libuv functions, uv_async_send can be called from another thread. */

也就是说配合uv_async_send,可以唤醒持有async的消息队列,并调用async的回调,而且这个是跨线程的,只保证uv_async_send调用一次之后,callback也必然至少调用一次,但是因为是很多线程可以同时发送唤醒消息,所以,也可能被多次调用啦。

单线程例子

/* * test_async.cc * * Created on: 2015年2月10日 */#include <stdlib.h>#include <stddef.h>#include <stdio.h>#include <string.h>#include <node/uv.h>uv_async_t async;uv_loop_t* loop;void close_cb(uv_handle_t* handle);void async_cb(uv_async_t* handle, int status);void close_cb(uv_handle_t* handle){printf("close the async handle!\n");}void async_cb(uv_async_t* handle, int status){printf("async_cb called!\n");uv_thread_t id = uv_thread_self();printf("thread id:%lu.\n", id);uv_close((uv_handle_t*)&async, close_cb);//如果async没有关闭,消息队列是会阻塞的}int main(){loop = uv_default_loop();uv_thread_t id = uv_thread_self();printf("thread id:%lu.\n", id);uv_async_init(loop, &async, async_cb);uv_async_send(&async);uv_run(loop, UV_RUN_DEFAULT);return 0;}
执行结果
thread id:140231151310656.async_cb called!thread id:140231151310656.close the async handle!

程序执行之后,就退出了,那是因为我们调用了uv_close,如果不调用uv_close,程序的消息队列会一直处于等待状态。

多线程版本

/* * test_async_thread.cc * * Created on: 2015年2月10日 */#include <stdlib.h>#include <stddef.h>#include <stdio.h>#include <string.h>#include <node/uv.h>uv_async_t async;uv_loop_t* loop;void close_cb(uv_handle_t* handle);void async_cb(uv_async_t* handle, int status);void sub_thread(void* arg);void close_cb(uv_handle_t* handle){printf("close the async handle!\n");}void async_cb(uv_async_t* handle, int status){printf("async_cb called!\n");uv_thread_t id = uv_thread_self();printf("thread id:%lu.\n", id);uv_close((uv_handle_t*)&async, close_cb);//如果async没有关闭,消息队列是会阻塞的}/** * */void sub_thread(void* arg){uv_thread_t id = uv_thread_self();printf("sub thread id:%lu.\n", id);uv_async_send(&async);}int main(){loop = uv_default_loop();uv_thread_t id = uv_thread_self();printf("thread id:%lu.\n", id);uv_async_init(loop, &async, async_cb);//创建子线程uv_thread_t thread;uv_thread_create(&thread, sub_thread, NULL);uv_run(loop, UV_RUN_DEFAULT);uv_thread_join(&thread);//等待子线程完成return 0;}
执行之后,输出如下

thread id:139936525506368.sub thread id:139936508737280.async_cb called!thread id:139936525506368.close the async handle!

可以看到,uv_async_send是可以在另一个线程中调用的。

0 0