Reputation: 4343
This is a minimal example based on a code that was handed to me:
// Example program
#include <iostream>
#include <string>
#include <thread>
int main()
{
std::cout << "Start main\n";
int i = 0;
auto some_thread = std::thread([&]() {
std::cout << "Start some thread\n";
while(i++ < 100) {
std::cout << i << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
});
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
auto some_thread2 = std::thread([&]() {
std::cout << "Start thread 2\n";
if (some_thread.joinable()) {
std::cout << "Thread 2 will join\n";
some_thread.join();
std::cout << "Thread 2 ended\n";
} else {
std::cout << "Thread 2 ended but didn't join\n";
}
});
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
if (some_thread.joinable()) {
std::cout << "Main will join\n";
some_thread.join();
std::cout << "Main ended\n";
return 0;
} else {
std::cout << "Main ended but didn't join\n";
return 1;
}
}
In short, the full program (as in this example) access to some std::thread
object from different threads and tries to join
and detach
to it.
I know it's a poor design, and that if you try to join a thread twice it will crash because after the first one finishes, then there's no thread associated with it. But this is not the case.
In this example it's crashing before the thread ends and with an Abort trap:6
. It just prints a couple of numbers and then crashes (the thread doesn't end its execution).
The code is not mine and I don't want a redesign. I just want to understand why it's crashing.
A final note, the original code was working somehow using semaphores and such (with some random crashes, though).
Upvotes: 0
Views: 1489
Reputation: 4343
The std::thread library is usually implemented on top of pthreads in an environment supporting pthreads (for example: libstdc++).
Quoting from pthread_join
linux documentation:
If multiple threads simultaneously try to join with the same thread, the results are undefined.
It also mentions that it returns the following error:
EINVAL Another thread is already waiting to join with this thread.
Upvotes: 0
Reputation: 109279
I know ... that if you try to join a thread twice it will crash because after the first one finishes, then there's no thread associated with it. But this is not the case.
On the contrary, that's exactly what's going on here. some_thread2
calls some_thread.join()
and while it's waiting on some_thread
to exit, the main thread is also calling some_thread.join()
. some_thread
is still active, and hasn't been joined at the time of the two checks, so joinable()
returns true in both cases.
One way to avoid the crash would be to add some_thread2.join();
before you check some_thread.joinable()
in the main thread (but if you do that, there's no need for the main thread to join some_thread
).
In any case, it's not clear why you want to join
the thread from two different threads, so it's difficult to suggest a better solution.
Upvotes: 1