三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

ZLToolKit 源码分析(四):TaskExecutor 与 WorkThreadPool 任务调度

ZLToolKit 源码分析(四):TaskExecutor 与 WorkThreadPool 任务调度

上篇分析了 ThreadPool 的底层实现,本文聚焦上层调度:TaskExecutorGetterImp 的负载均衡策略、WorkThreadPool 的双池设计,以及 ZLToolKit 如何实现"IO 线程"与"工作线程"的职责分离。

1. 线程池体系总览

TaskExecutorInterface (接口) └─ TaskExecutor (CPU 负载 + thread_local) ├─ ThreadPool (基础线程池) │ └─ EventPoller (IO 事件轮询) │ └─ EventPollerPool (IO 线程池单例) └─ WorkThreadPool (工作线程池单例)

ZLToolKit 将线程分为两类:

线程类型职责数量
IO 线程EventPollerPoolepoll 事件循环、Socket 读写CPU 核数
Worker 线程WorkThreadPool耗时计算、协议解析、媒体处理CPU 核数

2. TaskExecutorGetterImp — 执行器获取器

2.1 核心接口

classTaskExecutorGetterImp{public:// 获取第一个执行器TaskExecutor::PtrgetFirstExecutor();// 获取负载最低的执行器(轮转 + 负载加权)TaskExecutor::PtrgetExecutor();// 获取执行器数量size_tgetExecutorSize()const;// 遍历所有执行器voidforEach(constfunction<void(constTaskExecutor::Ptr&)>&cb);protected:vector<TaskExecutor::Ptr>_executors;atomic<size_t>_loop_index{0};};

2.2 getExecutor — 负载均衡算法

TaskExecutor::PtrTaskExecutorGetterImp::getExecutor(){autosize=_executors.size();if(size==0)returnnullptr;if(size==1)return_executors[0];// 策略:轮转 + 负载均衡// 1. 从轮转位置开始// 2. 找到负载最低的执行器// 3. 如果有负载为 0 的,直接返回(无锁快速路径)TaskExecutor::Ptr executor_min_load;floatmin_load=1.0f;for(size_t i=0;i<size;++i){autoidx=(_loop_index++)%size;auto&executor=_executors[idx];autoload=executor->
← 返回列表