You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多线程抢占长运行方法的线程安全实现方案咨询

C++线程安全解决方案:确保halt()正确中断或阻止executeInSeparateThread()

核心思路

要解决这个问题,关键是原子化控制runForAwhile()的启动时机,同时保证stopRunner()只在runForAwhile()运行时生效,或者彻底阻止runForAwhile()启动。通过原子状态变量结合原子操作实现线程安全的状态流转,避免竞态条件。

具体实现步骤

  1. 定义原子状态变量:用枚举标记当前执行状态,确保线程间状态可见性。
  2. 控制runForAwhile()启动:完成前置操作后,通过原子操作尝试切换状态为“运行中”,仅切换成功才启动任务。
  3. halt()分支处理:根据当前状态,要么阻止任务启动,要么调用stopRunner()中断运行中的任务。
  4. 前置操作插入检查(可选):若doBeforeThings()耗时较长,可在其中加入状态检查,提前响应halt请求。

完整代码示例

#include <atomic>

// 实际对应moveit::task_constructor::Task
class LongRunner
{
public:
  void runForAwhile();
  // 仅在runForAwhile运行时生效的中断方法
  void stopRunner();
};

// 实际对应BT::ThreadedAction
class ExecutionBase
{
public:
  virtual void executeInSeparateThread() = 0;
  // 等待执行线程结束,可重写做清理
  virtual void halt() = 0;
};

enum class ExecutionState {
    IDLE,      // 未启动runForAwhile
    RUNNING,   // runForAwhile正在执行
    HALTED     // 已收到halt请求
};

class MyExecution : public ExecutionBase
{
public:
  void executeInSeparateThread() override
  {
    doBeforeThings();

    // 原子操作:尝试将状态从IDLE改为RUNNING,避免竞态
    ExecutionState expected = ExecutionState::IDLE;
    if (state_.compare_exchange_strong(expected, ExecutionState::RUNNING)) {
        long_runner_.runForAwhile();
        // 任务正常完成,恢复IDLE状态
        state_.store(ExecutionState::IDLE);
    }

    doAfterThings();
  }

  void halt() override
  {
    ExecutionState expected = ExecutionState::IDLE;
    // 尝试将状态改为HALTED,如果当前是IDLE,说明runForAwhile还没启动
    if (state_.compare_exchange_strong(expected, ExecutionState::HALTED)) {
        // 无需调用stopRunner,直接阻止runForAwhile启动
    } else if (expected == ExecutionState::RUNNING) {
        // runForAwhile正在运行,调用stopRunner中断
        long_runner_.stopRunner();
        // 将状态标记为HALTED
        state_.store(ExecutionState::HALTED);
    }
    // 状态已为HALTED时无需操作

    // 调用基类方法等待线程结束
    ExecutionBase::halt();
  }

private:
  void doBeforeThings() {
    // 如果此方法耗时较长,可插入状态检查提前退出
    for (int i = 0; i < 10; ++i) {
        // 执行部分前置工作
        if (state_.load() == ExecutionState::HALTED) {
            return;
        }
    }
  }

  void doAfterThings() {
    // 执行后置清理工作
  }

  LongRunner long_runner_;
  std::atomic<ExecutionState> state_{ExecutionState::IDLE};
};

关键细节说明

  • 原子状态操作:compare_exchange_strong是原子操作,确保“检查状态+修改状态”的操作不会被其他线程打断,彻底避免“检查后状态被修改”的竞态条件。
  • 内存可见性:std::atomic默认使用memory_order_seq_cst内存顺序,保证所有线程能看到最新的状态值,无需额外互斥锁。
  • 兼容第三方库:完全不需要修改LongRunner和ExecutionBase的代码,仅在派生类中添加同步逻辑,符合约束要求。

内容的提问来源于stack exchange,提问作者mrjogo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 21:03:19