dxWorkerPool: 线程池管理
简介
在处理大量并发、独立的任务时,为每个任务都手动创建一个新的 Worker 是非常低效的。线程的创建和销毁本身会消耗系统资源,并且无限制地创建线程还会因资源竞争导致性能下降。
dxWorkerPool 提供了一个优雅的解决方案。它是一个线程池管理器,专为处理来自 dxEventBus 的事件流而设计。
核心思想:
dxWorkerPool 预先创建并维护一组固定数量的 Worker。当主线程通过 dxEventBus 触发一个被监听的事件时,线程池会自动将这个事件作为一个“任务”,从其内部的任务队列中取出,并将其分配给一个当前空闲的 Worker 去处理。
核心优势:
- 资源复用: 通过复用
Worker线程,避免了频繁创建和销毁线程带来的性能开销。 - 负载均衡: 自动将任务分发给空闲的
Worker,实现了简单的负载均衡。 - 流量控制: 内置任务队列,可以在任务量超过
Worker处理能力时进行缓冲,防止系统过载。 - 简化开发: 将复杂的任务分发和
Worker管理逻辑完全封装,开发者只需关注业务本身。
工作流程
dxWorkerPool 的工作流程完全是事件驱动的:
+-------------+ +------------+ +--------------+ +----------+
| Main Thread | | dxEventBus | | dxWorkerPool | | Worker 1 |
+-------------+ +------------+ +--------------+ +----------+
| | | |
| bus.fire('topic') | | |
|-------------------->| | |
| | on('topic', ...) | |
| |--------------------->| |
| | | 将任务加入内部队列 |
| | |--------------------->|
| | | |
| | | (发现空闲) 分配任务 |
| | |--------------------->|
| | | |
| | | | 执行 pool.callback()
| | | |-------------------->|
| | | |
| | | 通知任务完成 |
| | |<---------------------|
| | | |
| | | (变为空闲) |
| | |--------------------->|
API 概览
主线程 API
pool.init(file, bus, topics, [count], [maxsize])
(仅主线程可用) 初始化并启动线程池。这是使用线程池的第一步,且只能调用一次。
filestring: Worker 脚本的绝对路径。busobject:dxEventBus的实例,线程池将用它来监听任务。topicsstring[]: 一个字符串数组,定义了线程池需要监听的所有dxEventBus主题。任何发送到这些主题的事件都将被视为任务。countnumber: (可选) 线程池中的Worker数量,默认为 2。maxsizenumber: (可选) 内部任务队列的最大长度,默认为 100。如果队列已满,新任务会顶掉最老的任务。
Worker 线程 API
pool.callback(handlerFn)
(仅 Worker 线程可用) 在 Worker 脚本中注册用于处理任务的回调函数。
handlerFnFunction: 处理函数。当Worker从线程池接收到一个任务时,该函数会被调用。它接收一个task对象作为参数,其结构为{ topic: string, data: any }。
pool.getWorkerId()
(主线程和 Worker 线程均可用) 获取当前线程的 ID。在主线程中返回 'main',在 Worker 线程中返回由线程池分配的唯一 ID (例如 'pool__id0')。