Here is a simple thread trace program. The thread simply prints the first ten integers and then the "thread is done" message.
#include <iostream>
#include <vector>
#include <numeric>
#include <thread>
void f();
int main(int argc, const char * argv[]) {
std::thread t(f);
std::cout << "Thread start" << std::endl;
t.detach();
t.join();
std::cout << "Thread end" << std::endl;
return 0;
}
void f()
{
std::vector<int> a(10);
std::iota(a.begin(), a.end(), 0);
for(const int& i : a)
{
std::cout << i << std:: endl;
}
std::cout << "Thread is done." << std::endl;
}
However, when it runs, t.join throws a std::__1::system_error exception, somewhere in the libc ABI, leading the program to terminate with SIGABRT:
Thread start
0
1
2
3
4
5
6
7
8
9
Thread is done.
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: thread::join failed: No such process
Sometimes when it runs the exception in the main thread occurs (at the same place) before thread t runs (but it still does):
Thread start
libc++abi.dylib: terminating with uncaught exception of type std::__1::system_error: thread::join failed: No such process
0
1
2
3
4
5
6
7
8
9
Thread is done.
The issue is that both detach and join have a precondition that the thread is joinable, and both have as a post condition that joinable is false. This means that once you call one on a thread, attempting to call the other is invalid.
Secondly, the differing behavior you are seeing is due the timing of the execution of the thread and the main function. Sometimes the detach and join don't execute till after the thread runs, sometimes they run before, and anything in between.