mercredi 1 avril 2020

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.

#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. However I am getting error 22s (invalid argument) which according to the docs means that joinable() is false in some cases.

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.

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

Aucun commentaire:

Enregistrer un commentaire