详解c++ libuv工作队列
1、说明
libuv提供了一个线程池,可用于运行用户代码,libuv中的工作队列中的任务会在线程池中执行
libuv中的线程池在内部用于运行所有文件系统操作以及getaddrinfo()和getnameinfo()请求
libuv中的线程池的默认数量为4,可以在启动时修改环境变量UV_THREADPOOL_SIZE来修改,最大值为1024(1.30.0版本之前是128)
libuv中的线程池是全局的,并在所有事件循环之间共享,当特定的函数利用uv_queue_work()方法使用工作队列时,libuv会预分配线程池,以较小的内存开销(128个线程为1MB),来提高线程性能
以下三种类型的操作会在全局线程池中进行:
- 文件系统操作;
- DNS函数(getaddrinfo和getnameinfo);
- 使用uv_queue_work()调度的用户代码;
需要注意的是,即使使用了线程池,libuv的方法也不是线程安全的
2、API
2.1、uv_queue_work
intuv_queue_work(uv_loop_t*loop, uv_work_t*req, uv_work_cbwork_cb, uv_after_work_cbafter_work_cb);
添加一个任务到工作队列中,在主线程中调用
loop:事件循环
req:传入到任务的数据,一般使用req.data参数传递
work_cb:执行方法
after_work_cb:执行方法完成后执行
work_cb方法会在函数中执行,after_work_cb方法在创建线程中执行
void(*uv_work_cb)(uv_work_t*req); void(*uv_after_work_cb)(uv_work_t*req,intstatus);
如果调用uv_cancel方法取消了队列,则uv_after_work_cb的status为UV_ECANCELED
2.2、uv_cancel
intuv_cancel(uv_req_t*req);
取消未执行的队列中的任务,在任务中调用
req为任务的参数
如果调用此方法取消了任务,则after_work_cb回调函数的status的值为UV_ECANCELED;
3、代码示例
#include#include #include #include voidprint(uv_work_t*req) { sleep(1); longnum=(long)req->data; printf("threadidis:%ld,numis:%d\n",uv_thread_self(),num); } voidafter_print(uv_work_t*req,intstatus) { printf("afterprint,reqdatais%d,statusis%d\n",req->data,status); } intmain() { uv_loop_t*loop=uv_default_loop(); uv_work_treq[5]; for(intindex=0;index<5;index++) { req[index].data=(void*)(long)index; uv_queue_work(loop,&req[index],print,after_print); sleep(1); } returnuv_run(loop,UV_RUN_DEFAULT); }
示例中的代码,每次执行print()方法都是在不同线程中,after_print()方法和main()方法在同一个线程中
以上就是详解c++libuv工作队列的详细内容,更多关于c++libuv工作队列的资料请关注毛票票其它相关文章!