libuv::线程池
libuv提供了一个线程池,可用于运行用户代码并在循环线程中得到通知。该线程池在内部用于运行所有文件系统操作以及getaddrinfo和getnameinfo请求。
其默认大小为4,但可以在启动时通过将UV_THREADPOOL_SIZE环境变量设置为任何值(绝对最大值为1024)来更改它 。
线程池是全局的,并在所有事件循环之间共享。
当特定的函数利用uv_queue_work()线程池时(即使用时),libuv预分配并初始化允许的最大线程数 UV_THREADPOOL_SIZE。
这会导致相对较小的内存开销(128个线程约为1MB),但会在运行时提高线程性能。
#include <cstdio> #include <stdio.h> #include <stdlib.h> #include <libuv/uv.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> long fib_(long t) { if (t == 0 || t == 1) return 1; else return fib_(t - 1) + fib_(t - 2); } void fib(uv_work_t* req) { int n = *(int*)req->data; if (random() % 2) sleep(1); else sleep(3); long fib = fib_(n); fprintf(stderr, "输入 %d 计算结果 %lu\n", n, fib); } void after_fib(uv_work_t* req, int status) { fprintf(stderr, "输入 %d 已完成!\n", *(int*)req->data); } int main() { //定义一个事件轮询 uv_loop_t* loop = uv_default_loop(); //将10个计算任务放入线程池中。 int data[10]; uv_work_t req[10]; for (int i = 0; i < 10; i++) { data[i] = i; //传递任意参数 req[i].data = (void*)&data[i]; //libuv提供了线程池 //但是只能同时执行4个(可以修改 UV_THREADPOOL_SIZE 环境变量设置)。 //线程函数会在单独的线程中被启动, 并传入 uv_work_t 结构, //一旦函数返回, 就会调用 after_fib 函数, 同时也传入 uv_work_t 结构的指针. uv_queue_work(loop, &req[i], fib, after_fib); } return uv_run(loop, UV_RUN_DEFAULT); }