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.
Could be the result of trying to join threads that weren't started.
I was getting this error when I was joining an array for threads like this:
for (auto& th : threads) th.join();
Then I re-wrote with a manual for loop which gave me no errors:
for (i = 0; i< numthreads; i++)
threads[i] = thread(start,i+1);
I think it's because I declared the array like this:
std::thread threads[MAXTHREADS];
And so it was trying to join threads I hadn't started.
Full code for reference:
#include <sched.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <thread> // std::thread
#include <mutex> // std::mutex
using namespace std;
mutex mtx; // mutex for critical section
#define MAXTHREADS 10
#define MAXTIMES 1
int data[MAXTHREADS];
int start(int id) {
int stride = 64, dummy;
mtx.lock();
for(int times = 0; times < MAXTIMES; times++) {
for (int i = 0; i < MAXTHREADS; i = i + 1) {
//dummy = data[i]; //sim a read from every slot in the array
cout << data[i] << ", ";
}
cout << endl;
}
mtx.unlock();
return 0;
}
int main()
{
std::thread threads[MAXTHREADS];
int i;
int numthreads = 6;
for(int i = 0; i < MAXTHREADS; i++)
data[i] = i;
printf("Creating %d threads\n", numthreads);
for (i = 0; i< numthreads; i++)
threads[i] = thread(start,i+1);
for (i = 0; i< numthreads; i++)
threads[i].join();
//for (auto& th : threads) th.join();
printf("All threads joined\n");
return 0;
}
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