: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(constfunctionvoid(constTaskExecutor::Ptr)cb);protected:vectorTaskExecutor::Ptr_executors;atomicsize_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;isize;++i){autoidx=(_loop_index++)%size;autoexecutor=_executors[idx];autoload=executor-