ConcurrencyWorkerEngineering

用一个小实验,理解 Worker 的退出边界

创建、消息入队、处理与退出。把时间顺序展开,观察消息与资源有效期之间的关系。

并发模块中的很多边界问题,都需要回到一个具体问题:某个操作发生时,接收它的对象还处于什么状态?

本站的 Worker 生命周期实验 将创建、发送、处理和退出分成独立步骤。每一步都由手动操作推进,方便重复观察相同的顺序。

先观察四个状态

实验中,Worker 有四个状态:未创建、运行中、退出中和已退出。

状态 可以做什么 需要关注什么
未创建 创建实例 消息接收对象尚不存在
运行中 发送消息、处理消息、请求退出 接收条件与队列顺序
退出中 完成退出 新操作是否还允许进入
已退出 重新创建 新旧实例是否能够区分

这张表是演示的规则。真实运行时可能存在更多内部状态,接口允许的操作也可能不同。

发送成功与处理完成是两个步骤

先创建 Worker,连续发送两条消息。它们会进入队列,此时“已处理”仍然为零。点击“处理下一条”后,队列中的第一条消息才会被取出。

在这个模型里,发送的结果表示消息进入了队列。处理结果则需要观察后续步骤。将两者分别记录,才能说明消息当前处于什么阶段。

// 用于解释本页模型的伪代码,不是具体运行时的实现。
bool send(Message message) {
    if (state != Running) {
        return false;
    }
    pending.push(message);
    return true;
}

可以用这组操作观察:创建 → 发送两次 → 处理一次。此时队列中剩余一条,日志中有两次入队和一次处理记录。

请求退出时,队列如何处理

本实验选择一种清晰的退出策略:进入退出中后停止接收消息,并取消尚未处理的消息。 每条取消记录都包含消息编号和实例编号。

这样做便于观察退出边界。它不意味着所有 Worker 都应当采用相同策略:具体系统可能排空队列、取消任务,或为不同类型的任务提供不同约定。

阅读真实实现时,应先确认退出策略,再检查状态变化、消息处理与资源释放是否满足该策略。

用实例编号区分新旧上下文

退出后重新创建,实例编号会增加。新的消息与新的实例关联,日志仍然保留旧实例的事件。

这让一个容易被忽略的问题变得可见:名称相同的 Worker,在不同创建周期内属于不同实例。分析消息和回调时,需要知道它们属于哪个创建周期。

一组可以重复的观察步骤

  1. 创建实例,发送两条消息。
  2. 处理第一条,核对队列与日志。
  3. 请求退出,观察第二条消息被取消。
  4. 确认发送按钮已禁用,再完成退出。
  5. 重新创建,观察实例编号变化。
  6. 点击重置,恢复初始状态。

实验不执行实际的 C++ 线程,也不进行性能测量。它将状态、消息和退出策略拆开,作为理解工程边界的一个起点。

相关项目:OpenHarmony Worker。

ON THIS PAGE / 目录