libuv线程池

libuv提供了一个线程池,可用于运行用户代码并在循环线程中得到通知。该线程池在内部用于运行所有文件系统操作以及getaddrinfo和getnameinfo请求。
其默认大小为4,但可以在启动时通过将UV_THREADPOOL_SIZE环境变量设置为任何值(绝对最大值为1024)来更改它 。
线程池是全局的,并在所有事件循环之间共享。
当特定的函数利用uv_queue_work()线程池时(即使用时),libuv预分配并初始化允许的最大线程数 UV_THREADPOOL_SIZE。
这会导致相对较小的内存开销(128个线程约为1MB),但会在运行时提高线程性能。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <uv.h>

void fib(uv_work_t* req)
{
    
    
    int n = *(int*)req->data;
    if (n == 3) {
    
    
        sleep(2);
    }
    fprintf(stderr, "输入 %d 计算结果 %lu\n", n, n + 1);
}

void after_fib(uv_work_t* req, int status)
{
    
    
    fprintf(stderr, "输入 %d 已完成!\n", *(int*)req->data);
}

int main(void)
{
    
    
    //定义一个事件轮询
    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);
}

执行结果如下:

NuttShell (NSH) NuttX-10.1.0-RC0
nsh> hello
输入 0 计算结果 1
输入 1 计算结果 2
输入 2 计算结果 3
输入 4 计算结果 5
输入 5 计算结果 6
输入 6 计算结果 7
输入 7 计算结果 8
输入 8 计算结果 9
输入 9 计算结果 10
输入 0 已完成!
输入 1 已完成!
输入 2 已完成!
输入 4 已完成!
输入 5 已完成!
输入 6 已完成!
输入 7 已完成!
输入 8 已完成!
输入 9 已完成!
输入 3 计算结果 4
输入 3 已完成!
nsh> 

猜你喜欢

转载自blog.csdn.net/u013318019/article/details/118113249