[std :: thread具有奇怪的joinable()行为

问题描述 投票:0回答:1

我正在尝试实现一个线程列表,其中一个线程通过std::thread::join与下一个线程通信,直到完成所有作业为止。

#include <iostream>
#include <thread>
#include <chrono>
#include <vector>
#include <sstream>
#include <stdio.h>

std::vector<std::thread> workers;

void f1(void)
{
  std::cout<<"begin f1"<<std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(1));
  std::cout<<"end f1"<<std::endl;
}

void f2(int sleep_for, std::thread & previous_thread)
{
  try
  {
    previous_thread.join();
    std::cout<<"begin f2"<<std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout<<"end f2"<<std::endl;
  }
  catch (const std::system_error& ex)
  {
    std::stringstream ss;
    ss << ex.code() << '\n';
    ss << ex.code().message() << '\n';
    ss << ex.what() << '\n';
    printf("%s",ss.str().c_str());
  }
}

int main(void)
{
  std::cout<<0<<std::endl;
  workers.emplace_back(&f1);
  for(int i=0;i<3;i++)
  {
    std::cout<<i+1<<std::endl;
    workers.emplace_back(&f2, i, std::ref(workers.back()));
  }
  workers.back().join();
  /*
  std::thread t(&f1);
  std::thread t1(&f2, 0, std::ref(t));
  std::thread t2(&f2, 1, std::ref(t1));                                                                                                                                                                                                        
  std::thread t3(&f2, 2, std::ref(t2));
  t3.join();
  */
  return 0;
}

在此代码中,您可以看到我正在旋转4个线程,第一个线程之后的每个线程都应在前一个线程上按join,以便它将等待它结束。但是我收到错误22s(无效参数),根据文档,这意味着在某些情况下joinable()为false。

有时执行的确会使它经过所有线程,但是~thread中会引发异常,导致程序在退出前崩溃。

我在这里做错了什么?该文档对此非常直截了当,所以我不确定我缺少什么

编辑:我标记为正确的答案确实指出了代码的问题,但是我选择的解决方案是使用std::list而不是std::vector

我正在尝试实现一个线程列表,其中一个线程通过std :: thread :: join与下一个线程进行通信,直到所有工作完成为止。 #include #include&...

c++ c++11 stdthread
1个回答
2
投票

workers.emplace_back(&f2, i, std::ref(workers.back()));

© www.soinside.com 2019 - 2024. All rights reserved.