Create a std::thread object in thread A, join in thread B - c++

Is it allowed to call join() on a std::thread object that was created in a different thread, given that the object is properly synchronized between threads?
For example:
void cleanup(std::thread t)
{
t.join();
}
int main()
{
std::thread t{[] { /* something */ }};
std::thread c{cleanup, std::move(t)};
c.join();
}

Yes. join() can be called on a valid thread object by any thread except by the thread itself.
Error Conditions
resource_deadlock_would_occur if this->get_id() == std::this_thread::get_id().
no_such_process if the thread is not valid
invalid_argument if joinable() is false

Related

If I create two std::thread, how can I identify which thread ends first

I want to create two std::thread processes. Then I want to figure out which thread ended first and end the other thread if it is still running (probably by calling its destructor?). I would like to only use the std libraries. I'm guessing I need to do something with std::atomic and/or std::future, or implement a callback?
int process1( void );
int process2( void );
std::thread first (process1() );
std::thread second (process2() );
//check which thread is done first and call join() on that thread to end it nicely?
//kill the other thread if its not done or call join() if it is done?
You can't just end a thread from outside the thread itself. You have to signal the thread in some way that it needs to stop. You can do this with a std::atomic_boolfor example.
Something like this:
// thread-safe output
#define con_sync_out(m) do{std::ostringstream o; o<<m<<'\n'; std::cout<<o.str();}while(0)
#define con_sync_err(m) do{std::ostringstream o; o<<m<<'\n'; std::cerr<<o.str();}while(0)
// random numbers
template<typename Integer>
Integer random(Integer lo, Integer hi)
{
thread_local std::mt19937 mt{std::random_device{}()};
return std::uniform_int_distribution<Integer>(lo, hi)(mt);
}
// stuff to do
void do_work(char const* id, int a, int b, std::atomic_bool& done)
{
// check if done == true (signal to stop)
while(!done && a < b)
{
++a;
con_sync_out(id << ": " << a << "/" << b);
std::this_thread::sleep_for(std::chrono::milliseconds(random<int>(500, 1000)));
}
done = true;
}
int main()
{
std::atomic_bool done = false; // signal flag
std::thread t1(do_work, "A", random<int>(0, 10), random<int>(10, 20), std::ref(done));
std::thread t2(do_work, "B", random<int>(0, 10), random<int>(10, 20), std::ref(done));
t1.join();
t2.join();
}
There's no standard/easy way to kill a thread in C++. They're not like processes.
Either detach() them both and wait in your main thread for a std::conditional_variable notification from the fastest thread if you don't mind letting the slower one finish in the background.
Or join() them both and periodically check for the std::conditional_variable in each thread to notify that the other one has finished, and then abort by returning earlier.
If neither join() nor detach() have been called before a non-empty std::thread is destroyed, then the program simply terminates.

Can std::thread::join() be called from a non parent thread?

A::thread was created by main thread. Can I join A::thread into the thread goo ?
struct A {
std::thread thread;
void foo() {
thread=std::thread{[]() { sleep(10); }};
}
};
void goo(A& a) {
a.thread.join();
}
int main() {
A a;
a.foo();
std::thread other_thread{goo, a};
other_thread.join();
};
Yes, you may. The behavior of std::thread::join is (emphasis mine):
Blocks the current thread until the thread identified by *this
finishes its execution.
It says quite explicitly "current thread", not "parent thread". Any thread can join with any other thread, so long as it has a valid handle to that other thread.
Though you have to mindful of data races when using references to thread objects. Two different threads attempting to join the same third one would be... bad.

std::thread thread spun off in object, when does it terminate?

If I spin off an std::thread in the constructor of Bar when does it stop running? Is it guaranteed to stop when the Bar instance gets destructed?
class Bar {
public:
Bar() : thread(&Bar:foo, this) {
}
...
void foo() {
while (true) {//do stuff//}
}
private:
std::thread thread;
};
EDIT: How do I correctly terminate the std::thread in the destructor?
If I spin off an std::thread in the constructor of Bar when does it
stop running?
the thread will run as long as it executing the callable you provided it, or the program terminates.
Is it guaranteed to stop when the Bar instance gets destructed?
No. In order to guarantee that, call std::thread::join in Bar destructor.
Actually, if you hadn't call thread::join or thread::detach prior to Bar::~Bar, than your application will be terminated by calling automatically to std::terminate. so you must call either join (preferable) or detach (less recommended).
you also want to call therad::join on the object destructor because the spawned thread relies on the object to be alive, if the object is destructed while your thread is working on that object - you are using destructed object and you will have undefined behavior in your code.
Short answer: Yes and no. Yes, the thread ends, but not by the usual way (killing the thread), but by the main thread exiting due to a std::terminate call.
Long answer: The thread can only be safely destructed when the underlying function (thread) has finished executing. This can be done in 2 ways
calling join(), which waits for the thread to finish (in your case, never)
calling detach(), which detaches the thread from the main thread (in this case, the thread will end when the main thread closes - when the program terminates).
If the destructor is called if all of those conditions don't apply, then std::terminate is called:
it was default-constructed
it was moved from
join() has been called
detach() has been called
The C++ threading facilities do not include a built-in mechanism for terminating a thread. Instead, you must decide for yourself: a) a mechanism to signal the thread that it should terminate, b) that you do not care about the thread being aborted mid-operation when the process terminates and the OS simply ceases to run it's threads any more.
The std::thread object is not the thread itself but an opaque object containing a descriptor/handle for the thread, so in theory it could be destroyed without affecting the thread, and there were arguments for and against automatic termination of the thread itself. Instead, as a compromise, it was made so that destroying a std::thread object while the thread remained running and attached would cause the application to terminate.
As a result, In it's destructor there is some code like this:
~thread() {
if (this->joinable())
std::terminate(...);
}
Here's an example of using a simple atomic variable and checking for it in the thread. For more complex cases you may need to consider a condition_variable or other more sophisticated signaling mechanism.
#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>
class S {
std::atomic<bool> running_;
std::thread thread_;
public:
S() : running_(true), thread_([this] () { work(); }) {}
void cancel() { running_ = false; }
~S() {
if ( running_ )
cancel();
if ( thread_.joinable() )
thread_.join();
}
private:
void work() {
while ( running_ ) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "tick ...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::cout << "... tock\n";
}
std::cout << "!running\n";
}
};
int main()
{
std::cout << "main()\n";
{
S s;
std::this_thread::sleep_for(std::chrono::milliseconds(2750));
std::cout << "end of main, should see a tock and then end\n";
}
std::cout << "finished\n";
}
Live demo: http://coliru.stacked-crooked.com/a/3b179f0f9f8bc2e1

Can the thead joinable-join have a race condition? how do you get around it?

Lets say I have the following class
class A
{
public:
A()
{
my_thread=std::thread(std::bind(&A::foo, this));
}
~A()
{
if (my_thread.joinable())
{
my_thread.join();
}
}
private:
std::thread my_thread;
int foo();
};
Basically, if my thread completes between the joinable and join calls, then my_thread.join will wait forever? How do you get around this?
Basically, if my thread completes between the joinable and join calls, then my_thread.join will wait forever?
No. A thread is still joinable after it has completed; it only becomes unjoinable once it has been joined or detached.
All threads must be joined or detached before the controlling thread object is destroyed.

Deleting boost::thread descendant

I am trying to write a class that would run a thread upon its object creation and stop the thread once the object gets deleted.
class MyThread : public boost::thread {
public:
MyThread() : bAlive(true) {
boost::thread(&MyThread::ThreadFunction,this);
}
~MyThread() {
{
boost::unique_lock<boost::mutex> lock(Mutex);
bAlive=false;
}
ConditionVariable.notify_one();
join();
}
private:
volatile bool bAlive;
boost::mutex Mutex;
boost::condition_variable ConditionVariable;
void ThreadFunction() {
boost::unique_lock<boost::mutex> lock(Mutex);
while(bAlive) {
ConditionVariable.timed_wait(lock,boost::get_system_time()+ boost::posix_time::milliseconds(MAX_IDLE));
/*******************************************
* Here goes some code executed by a thread *
*******************************************/
}
}
};
Theoretically, I want to wake the thread up instantly as soon as it needs to be finished, so I had to use timed_wait instead of Sleep.
This works fine until I try to delete an object of this class. In most cases, it deletes normally, but occasionally it causes an error either in condition_variable.hpp, thread_primitives.hpp or crtexe.c. Sometimes I am notified that "Free Heap block 3da7a8 modified at 3da804 after it was freed", and sometimes I'm not. And yes, I'm aware of the spurious wakeups of timed_wait, in this case it's not critical.
Can you please point me to the source of my problem? What am I doing wrong?
I see what you're trying to do but it doesn't work as you expect:
MyThread foo;
default constructs a boost::thread (because MyThread is derived from boost::thread).
The default constructor creates a boost::thread instance that refers to Not-a-Thread.
MyThread() {
boost::thread(&MyThread::ThreadFunction,this);
}
is actually creating a different thread and you're ignoring the returned object (the valid thread).
~MyThread() {
// ...
join();
}
is then trying to join the default constructed thread (which throws an exception inside the destructor) and you never join the thread that actually does the work.
First of all, don't derive from boost::thread. Create a member variable instead:
class MyThread {
// ...
private:
// ...
boost::thread _thread;
};
In the constructor, create and assign a thread to that member variable:
MyThread() {
_thread = boost::thread(&MyThread::ThreadFunction,this);
}
and call its join() in your destructor.
~MyThread() {
// ...
_thread.join();
}
That should fix your problem.
However, if you simply want to exit the thread when your object is destroyed (and don't have to wake it up while its running), you can use a different approach. Remove the mutex and the condition variable and use interrupt instead. This will cause sleep() to throw an exception so you have to catch it:
void ThreadFunction() {
try {
for(;;) {
boost::this_thread::sleep(boost::posix_time::milliseconds(MAX_IDLE));
// Here goes some code executed by a thread
}
} catch( const boost::thread_interrupted& e ) {
// ignore exception: thread interrupted, exit function
}
}
This will instantly exit the ThreadFunction when the thread is interrupted. If you don't need the thread to sleep every cycle, you can replace it with boost::this_thread::interruption_point(). This will just throw an exception if the thread is interrupted.
Now you can simply interrupt the thread in the destructor:
MyThread::~MyThread() {
_thread.interrupt();
_thread.join();
}