I just had a breakthrough with this. I've been looking for a simple and general solution. Here it is.
Using the Boost C++ Libraries, create a signal that returns a boolean. Prior to its first use, connect the signal to a slot that returns false
. Create a boost::signals2::scoped_connection
within your thread that returns true
. This exploits the default behavior of boost::signals2::signal
return types that returns the value of the last slot called. By using the scoped_connection
at the beginning of your thread, this slot only remains connected while thread is running. Also, Boost signals2::signal
s contain internal mutexes that maintain thread safety.
#include <thread>
#include <boost/signals2.hpp>
int main(int argc, char* argv[])
{
//This can be in a class or someplace else
boost::signals2::signal<bool ()> ThreadRunning;
// Be sure to capture 'this' if used in a class
ThreadRunning.connect([]() {return false;});
auto t = std::thread([]()
{
// 'c' is an arbitrary variable name.
boost::signals2::scoped_connection c(ThreadRunning.connect[]() {return true;}));
// Do your stuff.
});
if (TreadRunning())
//Do stuff if the thread is still running
t.join();
return 0;
}
If the thread hasn't joined, but you want to see if it's completed running, you can insert an additional scope to your thread.
auto t = std::thread([]()
{
{
boost::signals2::scoped_connection c(ThreadRunning.connect[]() {return true;}));
// Do your stuff.
}
});
With this method, calling ThreadRunning()
will return false
even through the thread isn't joined.
While this method is threadsafe, there is the possibility that the thread will complete between when you call your signal and completing whatever you use this logic for.