libuv 提供了一个线程池,可用于运行用户代码,libuv 中的工做队列中的任务会在线程池中执行ios
libuv 中的线程池在内部用于运行全部文件系统操做以及 getaddrinfo() 和 getnameinfo() 请求api
libuv 中的线程池的默认数量为4,能够在启动时修改环境变量 UV_THREADPOOL_SIZE 来修改,最大值为 1024(1.30.0版本以前是128)安全
libuv 中的线程池是全局的,并在全部事件循环之间共享,当特定的函数利用 uv_queue_work() 方法使用工做队列时,libuv 会预分配线程池,以较小的内存开销(128个线程为1MB),来提升线程性能函数
如下三种类型的操做会在全局线程池中进行:oop
须要注意的是,即便使用了线程池,libuv 的方法也不是线程安全的性能
int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb);
添加一个任务到工做队列中,在主线程中调用线程
loop: 事件循环code
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, int status);
若是调用 uv_cancel 方法取消了队列,则 uv_after_work_cb 的 status 为 UV_ECANCELED
int uv_cancel(uv_req_t* req);
取消未执行的队列中的任务,在任务中调用
req 为任务的参数
若是调用此方法取消了任务,则 after_work_cb 回调函数的 status 的值为 UV_ECANCELED;
#include <iostream> #include <pthread.h> #include <unistd.h> #include <uv.h> void print(uv_work_t *req) { sleep(1); long num = (long)req->data; printf("thread id is: %ld, num is: %d\n", uv_thread_self(), num); } void after_print(uv_work_t *req, int status) { printf("after print, req data is %d, status is %d\n", req->data, status); } int main() { uv_loop_t *loop = uv_default_loop(); uv_work_t req[5]; for (int index = 0; index < 5; index++) { req[index].data = (void *)(long)index; uv_queue_work(loop, &req[index], print, after_print); sleep(1); } return uv_run(loop, UV_RUN_DEFAULT); }
示例中的代码,每次执行 print() 方法都是在不一样线程中,after_print() 方法和 main() 方法在同一个线程中