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

如何让C++线程与主while循环完全并行且独立运行

问题根因

  • 你当前主循环阻塞的核心原因是调用了std::future::get(),该方法会同步等待异步任务执行完成后才会继续往下执行,所以必须等所有计时器线程跑完才会进入下一轮while循环。
  • 两个异步任务同时修改同一个chrono对象,无锁保护存在数据竞争,属于C++未定义行为,会出现计时异常。
  • 多线程同时向std::cout输出内容,没有同步保护会导致输出乱序、错乱。
  • 你在while循环内反复创建新的异步任务,且持有future不释放,还会导致内存持续增长。

调整方案

  1. 用std::thread替代std::async实现完全独立的后台线程,启动后调用detach()脱离主线程管控,自主运行。
  2. 每个计时器独立维护自身的计时变量,不要共享同一个计时对象,避免数据竞争。
  3. 加互斥锁保护std::cout等共享资源,保证多线程输出正常。
  4. 计时器线程只在程序初始化时启动一次,不要在while循环内重复创建。

修改后的mychrono.hpp

#include <time.h>
#include <iostream>
#include <sstream>
#include <mutex>

#ifndef mychrono_hpp
#define mychrono_hpp

// 全局互斥锁,保护cout输出
extern std::mutex g_io_mutex;

class Chronometer
{
    private:
        int hour, min, sec;
        bool is_running; // 控制计时器运行状态
    public:
        Chronometer();
        void start_chrono(); // 无需传入外部chrono,自身维护计时数据
        void stop_chrono(); // 停止计时器接口
        friend std::ostream& operator<<(std::ostream& flux, const Chronometer& t);
        ~Chronometer();
};
#endif

修改后的mychrono.cpp

#include "mychrono.hpp"
#include <unistd.h>
#include <thread>

std::mutex g_io_mutex;

Chronometer::Chronometer() : hour(0), min(0), sec(0), is_running(false)
{

}

void Chronometer::start_chrono()
{
    is_running = true;
    while(is_running) {
        sleep(1);
        sec++;

        if(sec > 59) {
            min++;
            sec = 0;
        }

        if(min > 59) {
            hour++;
            sec = 0;
            min = 0;
        }
        // 加锁保护cout输出避免乱序
        std::lock_guard<std::mutex> lock(g_io_mutex);
        std::cout << "chrono: " << *this << std::endl;
    }
}

void Chronometer::stop_chrono()
{
    is_running = false;
}

std::ostream& operator<<(std::ostream& flux, const Chronometer& t)
{
    flux << t.hour << ":" << t.min << ":" << t.sec;
    return flux;
}

Chronometer::~Chronometer()
{
    stop_chrono();
}

修改后的main.cpp

#include <iostream>
#include <thread>
#include <vector>
#include <unistd.h>
#include "mychrono.hpp"

int main()
{
    std::vector<Chronometer*> car_crono;
    
    for(int i = 0; i < 2; i++)
    {
        car_crono.push_back(new Chronometer);
        // 启动计时器线程,detach后在后台完全独立运行
        std::thread t(&Chronometer::start_chrono, car_crono[i]);
        t.detach();
    }
    
    // 主循环完全独立运行,不需要等待任何线程
    while (1) {
        std::lock_guard<std::mutex> lock(g_io_mutex);
        std::cout << "hello-world" << std::endl;
        // 可调整sleep时间控制hello-world的打印频率
        sleep(1);
    }
    
    // 实际项目添加退出逻辑后可执行资源清理
    for(auto crono : car_crono) {
        delete crono;
    }
    car_crono.clear();
    return 0;
}

调整后计时器线程和主循环完全并行运行,互不阻塞,同时加锁保证了输出不会乱码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:57:05