在抛出 'std::system_error 的实例后调用终止

Posted

技术标签:

【中文标题】在抛出 \'std::system_error 的实例后调用终止【英文标题】:terminate called after throwing an instance of 'std::system_error在抛出 'std::system_error 的实例后调用终止 【发布时间】:2021-08-24 14:46:38 【问题描述】:

我遇到了线程问题:

这是重现错误的代码:

using namespace std;

#include <stdio.h>
#include <time.h>
#include <iostream>
#include <math.h>
#include <cstdlib>
#include <unistd.h>

#include <iostream>
#include <sstream>
#include <thread>
#include <vector>

#include "mychrono.hpp"

int main()


    
    std::vector<Chronometer*> car_crono;
    Chronometer chrono, output_chrono;
    std::vector<std::thread> threads;


    while (1) 
       

        
        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], std::ref(chrono)));                     
            
             

        //std::cout << "Threads size: " << threads.size();
        for (auto &th : threads) 
                    th.join();
                    
            
       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>


//int Chronometer::hour(0), min(0), sec(0);

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




Chronometer& Chronometer::start_chrono(Chronometer& chrono)

 
  if(chrono.hour == 0 && chrono.min == 0 && chrono.sec == 0)
  
    bool condition = true;
    while(condition) 
      sleep(1);
      chrono.sec++;

      if(sec > 59) 
        chrono.min++;
        chrono.sec = 0;

      

      if(min > 59) 
        chrono.hour++;
        chrono.sec = 0;
        chrono.min = 0;
      
      if(chrono.sec == 10)
      
        condition = false;
      

      std::cout << "chrono: " << chrono << std::endl;

   

    

  return chrono;

我的chrono.hpp

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

#ifndef mychrono_hpp
#define mychrono_hpp

class Chronometer

    private:
        int hour, min, sec;
        //std::stringstream ss;
        //Chronometer chrono;

    public:

        Chronometer();
        Chronometer& start_chrono(Chronometer& chrono);
        Chronometer& finish_chrono(Chronometer& chrono);
        friend std::ostream& operator<<(std::ostream& flux, Chronometer t);
        Chronometer& operator=(const Chronometer& other);
        ~Chronometer();

;


#endif

我的目的只是在后台启动几个独立的计时器以获得结果。对于一个实例化的 Chronometer 对象,程序在最后崩溃并输出以下输出:

terminate called after throwing an instance of 'std::system_error'
  what():  Invalid argument
Abandon (core dumped) 

但以 2 个计时码表为例,踏板增加一个计时码表的速度比增加两个独立计时码表快 2 倍。

我是线程的初学者,所以我不知道为什么会这样运行

【问题讨论】:

您是否尝试过使用调试器?请出示minimal reproducible example @AlanBirtles 我在下面添加了更简单的代码示例来重现错误并更好地解释我面临的问题。 你应该在你的问题中edit,而不是将其作为答案发布 注意using namespace std在包含标准库头之前可能会导致错误/崩溃/奇怪的编译错误 你的新代码对我有用(一旦我修复了由于缺少函数实现而导致的链接器错误),请显示minimal reproducible example 【参考方案1】:

您的代码中存在一些问题。

    在您的while 循环中,在调用join 之后,将线程留在threads 向量中,在循环的下一次迭代中,您将再次在同一线程上调用join,@987654327 @ throws std::invalid_argument 如果你不止一次调用join。加入话题后拨打clear onthreads。 在start_chrono 内部,您有多个线程在修改chrono.sec 而没有同步,这会导致竞争条件,并非所有线程都满足chrono.sec == 10 条件,导致它们永远继续执行,因为条件if (sec &gt; 59) 应该大概是 if (chrono.sec &gt; 59) 永远不会是真的,因为 sec 不会改变。 当您在创建线程后调用join 时,main 将被阻塞并且无法执行任何其他工作。仅当您真正想要等待线程停止执行时才应调用 join

【讨论】:

以上是关于在抛出 'std::system_error 的实例后调用终止的主要内容,如果未能解决你的问题,请参考以下文章

在抛出“std::system_error”线程池的实例后调用终止

xmake经验总结1:解决c++ future/promise抛出std::system_error的问题

xmake经验总结1:解决c++ future/promise抛出std::system_error的问题

xmake经验总结1:解决c++ future/promise抛出std::system_error的问题

C++ 线程,std::system_error - 不允许操作? [复制]

Qt-5.14.0:QML 下的 Vulkan 导致 std::system_error:: 互斥锁失败