Libuv源码分析 —— 8. 线程池

网络I/O

  • 上一节 的学习中,我们已经搞明白了网络I/O的基本过程,并通过了解进程/线程间通信来熟悉这个流程。下面,让咱们学习线程池中的线程如何工作、并和主进程进行通信的吧!

image.png

线程池

  • Libuv 是基于事件驱动的异步库。对于耗时的操作。如果在 Libuv 的主循环里执行的话, 就会阻塞后面的任务执行。所以 Libuv 里维护了一个线程池。他负责处理 Libuv 中耗时 的操作,比如文件 io、dns、用户自定义的耗时任务(文件 io 因为存在跨平台兼容的问 题。无法很好地在事件驱动模块实现异步 io)
  • 线程池是全局的,并且在所有事件循环中共享
Thread pool work scheduling
数据类型
  • uv_work_t

    工作请求类型。

  • void (*uv_after_work_cb)uv_work_t *  req , int 状态

    uv_queue_work()在线程池上的工作完成后,将在循环线程上调用的回调。如果工作被取消使用状态将是。uv_cancel() UV_ECANCELED

API
  • int uv_queue_work(uv_loop_t* loopuv_work_t* requv_work_cb work_cbuv_after_work_cb after_work_cb)

    初始化一个工作请求,它将在线程池中的一个线程中运行给定的work_cb。一旦work_cb完成,将在循环线程上调用after_work_cb 。

    可以使用 取消此请求uv_cancel()

example
  • #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #include <uv.h>
    
    #define FIB_UNTIL 25
    uv_loop_t *loop;
    
    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, "%dth fibonacci is %lu\n", n, fib);
    }
    
    void after_fib(uv_work_t *req, int status) {
         
         
        fprintf(stderr, "Done calculating %dth fibonacci\n", *(int *) req->data);
    }
    
    /*
        我们将要执行fibonacci数列,并且睡眠一段时间,将阻塞和cpu占用时间长的任务分配
        到不同的线程,使得其不会阻塞event loop上的其他任务
    */
    int main() {
         
         
        loop = uv_default_loop();
    
        int data[FIB_UNTIL];
        uv_work_t req[FIB_UNTIL];   // 子线程的参数
        int i;
    
        for (i = 0; i < FIB_UNTIL; i++) {
         
         
            data[i] = i;
            // 可以通过void *data传递任何数据,使用它来完成线程之间的沟通任务
            req[i].data = (void *) &data[i];
            uv_queue_work(loop, &req[i], fib, after_fib);
        }
    
        return uv_run(loop, UV_RUN_DEFAULT);
    }
    
    /*
        执行结果
        0th fibonacci is 1
        2th fibonacci is 2
        3th fibonacci is 3
        Done calculating 0th fibonacci
        Done calculating 2th fibonacci
        Done calculating 3th fibonacci
        4th fibonacci is 5
        5th fibonacci is 8
        Done calculating 4th fibonacci
        Done calculating 5th fibonacci
        1th fibonacci is 1
        Done calculating 1th fibonacci
        8th fibonacci is 34
        Done calculating 8th fibonacci
        9th fibonacci is 55
        Done calculating 9th fibonacci
        6th fibonacci is 13
        Done calculating 6th fibonacci
        11th fibonacci is 144
        Done calculating 11th fibonacci
        7th fibonacci is 21
        Done calculating 7th fibonacci
        13th fibonacci is 377
        Done calculating 13th fibonacci
        14th fibonacci is 610
        Done calculating 14th fibonacci
        10th fibonacci is 89
        Done calculating 10th fibonacci
        12th fibonacci is 233
        Done calculating 12th fibonacci
        15th fibonacci is 987
        Done calculating 15th fibonacci
        16th fibonacci is 1597
        17th fibonacci is 2584
        Done calculating 16th fibonacci
        Done calculating 17th fibonacci
        18th fibonacci is 4181
        Done calculating 18th fibonacci
        20th fibonacci is 10946
        Done calculating 20th fibonacci
        22th fibonacci is 28657
        Done calculating 22th fibonacci
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值