Reputation: 676
The following test program compiles with g++ -o test -pthread -std=c++11 test.cpp
just fine:
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
using namespace std;
void foo(int);
int main()
{
vector<thread> threads(5);
for (int i = 0; i < 5; i++)
{
threads.push_back(thread(foo, i));
}
for (vector<thread>::iterator iter = threads.begin(); iter != threads.end(); iter++)
{
iter->join();
}
}
void foo(int id)
{
cout << "thread " << id << " started.";
this_thread::sleep_for(chrono::seconds(10));
cout << "thread " << id << " terminated.";
}
However, when run, it gives output similar to this:
terminate called after throwing an instance of 'std::system_error'
what(): Invalid argument
thread thread 2 started.1 started.thread 4 started.thread 3 started.thread 0 started.Aborted (core dumped)
I have no idea where this error is coming from. From debugging, I know that the error happens as soon as I try to join the first thread.
http://www.cplusplus.com/reference/thread/thread/join/ states that join will only throw invalid_argument
if the thread is not joinable.
http://www.cplusplus.com/reference/thread/thread/joinable/ states that a thread is not joinable only if:
As one can clearly see, the thread was not default-constructed.
I am never overwriting the thread with another thread object. The output of the program also shows that each thread is clearly running, as the "thread x started." statements are reached.
I am only calling join once for each thread.
If I put a 5-second pause between creation and joining, I get the same outout, so it's not a race issue. Although it is interesting that the output is still ordered in the same way. Any ideas?
Upvotes: 0
Views: 5037
Reputation: 106116
You shouldn't presize the vector
with 5 default-constructed threads, then ignore those while push_back
-ing additional ones. Your join
then tries to join the default-constructed threads and throws. Get rid of the (5)
, or move it to a reserve
call.
Upvotes: 5