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() 方法在同一個線程中