Search code examples
c++c++11vectorstdvectorstdthread

Threads in a vector can't be joined


I want to store a collection of threads in a vector, and join them all before exiting my program. I receive the following error when trying to join the first thread no matter how many I place in the collection:

system_error: thread::join failed: No such process

Here is some simple code that demonstrates my issue:

#include <thread>
#include <iostream>
#include <vector>
#include <functional>

using std::cout;
using std::endl;
using std::vector;
using std::thread;
using std::mem_fn;

int main()
{
  vector<thread> threads(1);
  threads.push_back(thread([]{ cout << "Hello" << endl; }));
  for_each(threads.begin(), threads.end(), mem_fn(&thread::join));

  // also tried --> for(thread &t : threads) t.join()
}

And I'm building it using the following (tried clang++ 4.2.1 and g++ 5.3.1):

g++ -o src/thread_test.o -c -std=c++14 src/thread_test.cpp -pthread
g++ -o thread_test src/thread_test.o -pthread

I see lots of examples doing just this around the internet. Did something change in the contract of <thread> or <vector> that's rendered these examples defunct?

NOTE: As an aside for future readers, I ended up adding the (1) constructor argument after trying {} assignment, which fails due to a private copy constructor. In trying to avoid the copy constructor I ended up allocating uninitialized threads -- careless mistake.


Solution

  • vector<thread> threads(1);

    This creates a thread which can be accessed at index 0.

    threads.push_back(thread([]{ cout << "Hello" << endl; }));

    This adds a second thread which can be accessed at index 1.

    for_each(threads.begin(), threads.end(), mem_fn(&thread::join));

    This is going to call join on both thread objects. However, the first one was never started therefore it is not joinable.

    Instead, you could replace vector<thread> threads(1); with vector<thread> threads; threads.reserve(1); and keep using push_back.