Reputation: 53
I am trying to simulate the boost::thread
's timed_join
functionality (I know it's deprecated) with calling pthread_timedjoin_np
on the native_handle
of an std::thread
. The problem is that despite joinable()
returns true, the join()
function throws.
#include <thread>
#include <chrono>
#include <iostream>
int main()
{
auto t = std::thread([]{
std::this_thread::sleep_for(std::chrono::milliseconds{100});
std::cout << "hello from thread\n";
});
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += 1;
if (int s = pthread_timedjoin_np(t.native_handle(), nullptr, &ts); s != 0)
{
std::cout << "timed out: " << s << std::endl;
}
if(t.joinable())
{
std::cout << "thread is joinable\n";
t.join();
}
return 0;
}
Everything works if the spawned std::thread
is still running when the pthread_timedjoin_np
gets called and timed outs of course. Why is this strange behaviour? Isn't it possible to "manipulate" std::thread
through its native handle?
Upvotes: 1
Views: 626
Reputation: 473447
If you go behind std::thread
's back with native_handle
, the standard library has no idea you've done this. Therefore, the result of thread::joinable
is not reliable. Or more accurately, "implementation-defined". The implementation might check if the handle has been joined. Or it might not.
So if you intend to manipulate a thread outside of the standard library's control, you need to commit to it. The simplest way would be to have your pthread_timedjoin_np
condition detach the thread
object if it successfully joined.
Upvotes: 2