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.
If you don't join these threads, you might end up using more resources than there are concurrent tasks, making it harder to measure the load. To be clear, if you don't call join , the thread will complete at some point anyway, it won't leak or anything.
const and Thread Safety The C++11 standard does not expect to be able to safely call non const functions simultaneously. Therefore all classes available from the standard, e.g. std::vector<>, can safely be accessed from multiple threads in the same manner.
Vectors are synchronized. Any method that touches the Vector 's contents is thread safe. ArrayList , on the other hand, is unsynchronized, making them, therefore, not thread safe.
To join a thread means to wait until that thread is live. When the thread exits, the thread calling join() will continue executing. Thus, in the above example, the thread (presumably main thread) that is calling a. join() and b.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With