任务队列 — TaskQueue、SerialTaskQueue、ConcurrentTaskQueue

第 14 课:任务队列 — TaskQueue、SerialTaskQueue、ConcurrentTaskQueue 对应源文件: trantor/utils/TaskQueue.h — 抽象基类 trantor/utils/SerialTaskQueue.h / SerialTaskQueue.cc — 串行执行队列 trantor/utils/ConcurrentTaskQueue.h / ConcurrentTaskQueue.cc — 并发线程池队列 一、为什么需要 TaskQueue? EventLoop 是单线程的,其中不能执行任何阻塞操作(数据库查询、文件 I/O、耗时计算),否则整条链路的 I/O 响应都会被拖慢。 TaskQueue 提供了一个"卸载阻塞任务"的机制: 1 2 3 4 5 6 [EventLoop 线程] [TaskQueue 线程] 收到玩家请求 │ → 投递到 TaskQueue ────────────►│ 执行 DB 查询(可阻塞) → 立即返回,处理下一个事件 │ 查询完成 │ → 回调投递回 EventLoop ◄── 收到结果,发送响应 ────────────┘ 这是异步编程的基本模式:不阻塞事件循环,把耗时操作委托给专用线程。 二、TaskQueue — 抽象基类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class TaskQueue : public NonCopyable { public: // 纯虚:子类实现具体的投递方式 virtual void runTaskInQueue(const std::function<void()> &task) = 0; virtual void runTaskInQueue(std::function<void()> &&task) = 0; virtual std::string getName() const { return ""; } // 同步执行:投递任务并阻塞等待完成(基类实现,子类免费获得) void syncTaskInQueue(const std::function<void()> &task) { std::promise<int> prom; std::future<int> fut = prom.get_future(); runTaskInQueue([&]() { task(); prom.set_value(1); // 任务完成,解锁调用方 }); fut.get(); // 阻塞等待 } }; syncTaskInQueue 的精妙之处: ...

March 29, 2025 · 8 min · 1504 words