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

C++多线程抛出std::system_error异常及计时逻辑错误求助

问题根因

1. 程序崩溃原因

你的std::thread向量threads每次循环都会追加新线程对象,但循环结束后没有清空,下一轮循环会继续往向量中新增内容,导致后续对已经执行过join、处于终止状态的线程对象重复执行join操作,触发std::system_error抛出Invalid argument错误。
另外你通过new创建的Chronometer对象从未执行delete释放,存在严重内存泄漏。

2. 计时速度翻倍原因

你所有线程都在修改同一个传入的全局chrono对象,没有做互斥保护,多个线程同时修改同一个变量属于数据竞争,自然会出现计数速度翻倍的异常情况。同时你的start_chrono方法存在逻辑错误:if(sec > 59)这里读取的是当前实例的sec成员,不是传入的参数chrono的sec成员,逻辑本身就不成立。


修复方案

  • 每次循环结束后清空threads和car_crono向量,释放堆内存,避免重复操作已终止的线程对象
  • 不需要额外传入chrono参数,直接操作当前Chronometer实例的成员变量即可,每个线程对应一个独立的Chronometer实例,就不会出现互相干扰的问题
  • 多线程输出内容需要加互斥锁,避免多个线程输出内容乱码
  • 修正start_chrono的逻辑,不要混用当前对象和参数对象的成员

修复后代码示例

main.cpp

#include <stdio.h>
#include <time.h>
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <sstream>
#include <thread>
#include <vector>
#include "mychrono.hpp"

int main()
{
    while (1) {
        std::vector<Chronometer*> car_crono;
        std::vector<std::thread> threads;

        for(int i = 0; i < 2; i++)
        {
            car_crono.push_back(new Chronometer);
        }

        for(int i = 0; i<2; i++)
        {
            threads.push_back(std::thread(&Chronometer::start_chrono, car_crono[i]));                     
        }

        for (auto &th : threads) {
            th.join();
        }
        // 释放堆内存
        for (auto p : car_crono) {
            delete p;
        }
        std::cout << "Hello-world" << std::endl;
    }
}

chrono.cpp

#include "mychrono.hpp"
#include <time.h>
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <sstream>
#include <thread>
#include <mutex>

// 互斥锁保护cout输出
static std::mutex cout_mtx;

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

}

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

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

        if(min > 59) {
            hour++;
            sec = 0;
            min = 0;
        }
        if(sec == 10)
        {
            condition = false;
        }

        std::lock_guard<std::mutex> lock(cout_mtx);
        std::cout << "chrono: " << *this << std::endl;
   }
}

mychrono.hpp

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

#ifndef mychrono_hpp
#define mychrono_hpp

class Chronometer
{
    private:
        int hour, min, sec;
    public:
        Chronometer();
        void start_chrono();
        Chronometer& finish_chrono(Chronometer& chrono);
        friend std::ostream& operator<<(std::ostream& flux, Chronometer t);
        Chronometer& operator=(const Chronometer& other);
        ~Chronometer();
};
#endif

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 02:54:02