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

C++中如何在线程外获取atomic原子变量的值并触发对应业务逻辑

解决方案

代码优化核心要点

  • 给后台循环增加合理休眠,避免死循环占满CPU核心,休眠时长可设为100ms,远小于3秒的超时阈值,不会影响状态判断精度
  • 增加历史状态缓存,仅当状态实际发生变更时才调用prepareData(),减少无效调用开销
  • 原子变量使用标准load()/store()方法访问,保证跨线程操作的可见性和安全性
  • 修正原代码中变量名不一致的问题:头文件定义的是STATUS,后台线程中错误写为MC_COMPUTER_STATUS,统一变量命名
  • 头文件中不要直接定义全局原子变量,改为extern声明,放到cpp文件中定义,避免多文件引用时出现重复定义错误

修正后代码

ProtoApiManager.hpp

#include <atomic>
#include <chrono>
using namespace std::chrono;

// 状态变量声明
extern std::atomic_int STATUS;
// 超时常量统一管理
constexpr int NAV_COMMS_TIMEOUT_MS = 3000;

ProtoApiManager.cpp

#include "ProtoApiManager.hpp"
// 原子变量定义
std::atomic_int STATUS = ATOMIC_VAR_INIT(0);

void ProtoApiManager::startBgThread() {
    _keep_running = true;
    // 初始化上次接收数据的时间
    _last_status_msg_rx = MiscUtils::getTimeNow();
    _t_bg_tasks = std::thread(&ProtoApiManager::onThreadBgTasks, this);
}

void ProtoApiManager::onThreadBgTasks() {
    // 缓存上一次的状态,避免重复触发prepareData
    int last_status = STATUS.load(std::memory_order_relaxed);
    do {
        milliseconds currentTime = MiscUtils::getTimeNow();
        auto delta = currentTime - _last_status_msg_rx;
        int new_status = delta.count() > NAV_COMMS_TIMEOUT_MS ? 0 : 1;

        // 仅状态变化时更新并触发数据组装
        if (new_status != last_status) {
            STATUS.store(new_status, std::memory_order_relaxed);
            if (new_status == 0) {
                std::cout << "Time out OFFLINE" << std::endl;
            } else {
                std::cout << "Time out ONLINE" << std::endl;
            }
            prepareData();
            last_status = new_status;
        }
        // 休眠降低CPU占用
        std::this_thread::sleep_for(milliseconds(100));
    } while (_keep_running);
}

// UDP数据接收回调逻辑补充:每次收到合法数据时更新接收时间
void ProtoApiManager::onUdpDataReceived() {
    _last_status_msg_rx = MiscUtils::getTimeNow();
}

ProtoApiManager.process.cpp

#include "ProtoApiManager.hpp"

void ProtoApiManager::prepareData() {
    // 组装数据
    hardwareItemStatusMCComputer->set_hardwaretype(10);
    hardwareItemStatusMCComputer->set_hardwarename("MC Computer");
    // 读取原子变量最新值
    hardwareItemStatusMCComputer->set_hardwarestatus(STATUS.load(std::memory_order_relaxed));

    // UDP发送逻辑
}

额外注意事项

  • 如果prepareData()涉及非线程安全的资源操作,需要加互斥锁保护,或者把调用逻辑投递到指定的单线程执行
  • 程序退出时要主动将_keep_running设为false,并调用后台线程的join()方法回收资源,避免崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:45:01