Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusing a thread - boost vs std thread behaviour

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.

like image 698
aleksk Avatar asked Apr 06 '26 17:04

aleksk


2 Answers

Typically, as correctly pointed out above, all (joinable) threads need to be joined or detached before their object is destroyed.

Now, one (of many) differences between boost threads and std::thread is that Boost threads detach themselves inside their destructor which std::thread's do not; your incorrect usage of std::thread therefore correctly fires terminate().

PS: Do NOT (!!) believe the other commentors above that std::threads and boost::thread should behave "the same" - this is just not true!

like image 196
Skriptkiddie Avatar answered Apr 08 '26 14:04

Skriptkiddie


From std::thread::operator = ()

"If [the thread object] is joinable, terminate() is called."

like image 30
Sid S Avatar answered Apr 08 '26 15:04

Sid S



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!