【问题标题】: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

标签: c++ multithreading loops


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2018-01-06
    相关资源
    最近更新 更多