I seem to be getting different thread object assignment behaviour between boost and std threads. If I use boost threads, a thread member variable can be reassigned and the thread recreated. If I use std threads, I get a runtime error terminate called without an active exception
.
Here is the code in question (run, then replace std:: with boost::)
class ThreadTest
{
private:
std::thread mythread;
std::atomic<bool> running_;
int doSomeWork(){
int i=0;
cout << "starting" << endl;
while(running_){
cout << "working" << endl;
std::this_thread::sleep_for (std::chrono::seconds(1));
if (i>3){ break; } else { i++; }
}
running_ = false;
}
public:
void runThread(){
running_ = true;
mythread = std::thread(&ThreadTest::doSomeWork, this);
}
void joinThread(){
mythread.join();
}
};
int main(){
ThreadTest test;
test.runThread();
std::this_thread::sleep_for (std::chrono::seconds(10));
test.runThread();
test.joinThread();
return 0;
}
Output for boost::
starting
working
working
working
working
working
starting
working
working
working
working
working
Output for std::
starting
working
working
working
working
working
terminate called without an active exception
Aborted (core dumped)
This particular piece of code is used in a library which doesn't seem to have boost as a dependency. I would like to keep it that way, so is there a way to get the boost 'reassignment' behaviour using std threads?
EDIT - SOLUTION
I added an std::atomic<bool> threadInitialized_;
to the class which is set to true
in the thread function doSomeWork()
. My runThread()
method becomes:
void runThread(){
if(threadInitialized_)
mythread.join();
running_ = true;
mythread = std::thread(&ThreadTest::doSomeWork, this);
}
I am aware this will block the main thread until the spawned thread is done.