libuv源码剖析(四): 高效线程池Threadpool

这篇博客详细介绍了libuv如何通过线程池实现全异步操作,包括线程池模型、任务提交和取消、worker线程的工作方式,并通过示例代码展示了线程池的使用。libuv利用线程池处理同步任务,模拟异步效果,为网络编程提供高效解决方案。
摘要由CSDN通过智能技术生成

Introduction

在网络编程中, 始终都是基于Reactor模型的变种, 无论怎么演化, 核心组件都包括: Reactor实例(事件注册, 注销, 通知); 多路复用器(由操作系统提供, 比如kqueue, select, epoll); 事件处理器(handler)以及事件源(linux中这就是描述符)这四个组件.

一般,会单独启动一个线程运行Reactor实例来实现真正的异步操作。但是,依赖操作系统提供的系统调用来实现异步是有局限的,比如在Reactor模型中我们只能监听到:网络IO事件、signel(信号)、超时事件以及一些管道事件等,但这些事件也只是通知我们资源可读或者可写,真正的读写操作(read和write)还是同步的(也就是你必须等到read或者write返回,虽然linux提供了aio,但是其有诸多槽点),那么libuv的全异步是如何做到的呢?你可能会很快想到,就是启用单独的线程来做同步的事情,这也是libuv的设计思路,借用官网的一张图,说明一切:

这里写图片描述

由上图可以看到,libuv实现了一套自己的线程池来处理所有同步操作(从而模拟出异步的效果),下面就来看一下该线程池的具体实现吧!

线程池模型

几乎所有的线程池都遵守着下面这个模型(任务队列+线程池):

这里写图片描述

在libuv中, 事件队列借助自身的高线队列实现, 具体实现可参考我的另一篇博文: libuv源码剖析(一): 高效队列 Queue

接下来我们来看 threadpool 部分的实现.

首先, libuv对于 task 的定义:

struct uv__work {
  void (*work)(struct uv__work *w);
  void (*done)(struct uv__work *w, int status);
  struct uv_loop_s* loop;
  void* wq[2];
};

两个回调函数指针(一个是实际任务, 一个是任务做完之后的回调), void *wq[2]work queue 中的节点, 通过这个节点组成一条链.
至于loop用来标明在哪个loop中.

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值