简体   繁体   English

使用 std::thread 的奇怪 `joinable()` 行为

[英]Strange `joinable()` behavior with std::thread

I'm trying to implement a list of threads where one thread communicates to the next via std::thread::join that it is finished until all the jobs are accomplished.我正在尝试实现一个线程列表,其中一个线程通过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;
}

In this code you can see I am spinning up 4 threads and every thread after the first should join on the previous thread so it will wait for it to finish.在这段代码中,您可以看到我正在启动 4 个线程,第一个线程之后的每个线程都应该join前一个线程,以便等待它完成。 However I am getting error 22s (invalid argument) which according to the docs means that joinable() is false in some cases.但是,我收到错误 22s(无效参数),根据文档,这意味着在某些情况下joinable()是错误的。

Sometimes execution does make it past all the threading but then an exception is thrown in ~thread which causes the program to crash just before exiting.有时执行确实使它通过了所有线程,但随后在~thread中抛出异常,导致程序在退出之前崩溃。

What am I doing wrong here?我在这里做错了什么? The docs are really straight forward on this so I'm not sure what I'm missing文档在这方面非常直接,所以我不确定我错过了什么

Edit: the answer I marked as correct does point out the problem with the code but the solution i chose was to use std::list instead of std::vector编辑:我标记为正确的答案确实指出了代码的问题,但我选择的解决方案是使用std::list而不是std::vector

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

这会导致 UB,因为您将指针传递给工作人员的数据,然后增加它的大小,这可能会重新分配其所有成员,从而导致引用无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM