TaskPool 是 HarmonyOS 为了解决高并发、短耗时任务而设计的 系统级任务调度器。它的底层机制并非简单的 FIFO 队列,而是结合了现代并发理论的复杂调度系统。
1. TaskPool 的底层调度机制
TaskPool 的核心是 “生产者-消费者”模型 配合 系统负载感知:
-
集中调度器 (Global Scheduler) :TaskPool 维护一个全局任务队列。当你调用
taskpool.execute()时,任务会被推入这个队列。 -
共享线程池:系统底层维护着一个与 CPU 核心数绑定的线程池(由 FFRT,即 Function Flow Runtime 驱动)。这些线程跨应用共享,确保系统整体资源利用率最大化。
-
优先级感知的非公平调度:
- QoS (Quality of Service) :TaskPool 允许设置不同的优先级(
HIGH,MEDIUM,LOW)。 - 调度策略:高优先级任务会插队到队列前端,并分配到性能大核(Big Cores);低优先级任务则会被限制在能效小核(Little Cores)执行,甚至在系统高负载时被挂起。
- QoS (Quality of Service) :TaskPool 允许设置不同的优先级(
2. 是否存在任务窃取(Work Stealing)?
结论:是的,TaskPool 的底层 FFRT 框架支持 Work Stealing。
- 本地队列与全局队列:为了减少全局锁竞争,每个工作线程都有自己的 本地私有队列。
- 窃取机制:当某个线程处理完了自己本地队列的所有任务而处于空闲状态时,它会主动从其他繁忙线程的私有队列末尾“窃取”一个任务来执行。
- 收益:这种机制极大地减少了多核 CPU 下的 负载不均(Load Imbalance) 现象。即便你扔进去的任务耗时极度不均(有的 1ms,有的 100ms),系统也能保证所有核心都在干活,不会出现“一核有难,七核围观”。
3. 任务是否保证顺序执行?
结论:默认不保证顺序,但可以通过特定的 API 实现顺序性。
A. 默认行为:并发无序
因为 TaskPool 会将任务分发到多个线程并行执行,所以任务 1 可能先开始,但任务 2(如果计算简单)可能先完成。
B. 如何实现顺序执行?
如果你有“任务 A 必须在任务 B 之前完成”的需求,可以使用以下手段:
-
任务组 (TaskGroup) :虽然
TaskGroup主要是为了获取一组任务的最终结果,但你可以结合await来控制提交时机。 -
串行执行器 (SequenceRunner - HarmonyOS NEXT 新特性) :
- 机制:
SequenceRunner保证提交给它的任务会 按照提交顺序一个接一个地执行。 - 原理:它在内部维护了一个逻辑上的单行道。即使物理上有多个线程,它也保证在前一个任务完成前,不会启动下一个。
- 机制:
-
手动依赖管理:通过
Promise.then()或await链式调用。在任务 A 的返回回调里再提交任务 B。
4. 架构师的性能建议
| 场景 | 推荐做法 |
|---|---|
| 相互独立的大量任务 | 直接推入 TaskPool,利用 Work Stealing 榨干多核性能。 |
| 存在前后依赖的任务 | 使用 await 链式提交,或使用 SequenceRunner 维护时序。 |
| 紧急 UI 数据计算 | 必须设为 Priority.HIGH,否则可能在任务洪水中被延后。 |
总结
- 底层:FFRT 驱动,QoS 智能感知。
- 窃取:支持,用于平衡多核负载。
- 顺序:默认不保,顺序需求请用
SequenceRunner。