Question

I have the following code:

MyClass::aMethod()
{
    ...
    bool isStarted = false;

    boost::thread(boost::bind(&MyClass::CheckTimeoutThread, this, isStarted));

    ...//some time later
    isStarted = true;
    ...
}

MyClass::checkTimeoutThread(bool &isStarted)
{
    ...//some code here
    while(anotherFlag)
    {
        ...//do something
        if(isStarted)//ALWAYS THE INITIAL VALUE OF FALSE
        {
        }
        ...
    }
}

I was expected the isStarted variable can be used as a flag but I am wrong or I was doing something wrong.

Was it helpful?

Solution

The boost::thread will store copy of its arguments. But you can simulate a reference by passing a reference_wrapper with the help of boost::ref. Also note that you don't need to call boost::bind:

boost::thread t(&MyClass::CheckTimeoutThread, this, boost::ref(isStarted));

But note that you now have a race condiiton on isStarted. You need to either synchrise access to it with, say, mutexes, or use an atomic type, if available on your platform (if you have C++11, then you can use std::atomic<bool>, as suggested by @PeteBecker.)

Edit Obviously all of the above assumes that isStated lives at least as long as the thread that uses it. In practice, this means the thread must be done by the time aMethod returns. Alternatively, you can make isStarted a data member. But you still have to make sure to join the thread before the MyClass destructor destroys it.

OTHER TIPS

The biggest problem (besides std::ref or boost::ref required to pass references to thread), is that you are passing a reference to a temporary

MyClass::aMethod()
{
    ...
    bool isStarted = false;

}

/// Oops at the end of the method, `isStarted` no longer lives 

Any access through the stale reference is Undefined Behaviour after control leaves aMethod

May I suggest using proper synchronization: See it Live on Coliru

#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>

struct X
{
    std::condition_variable cv;
    std::mutex mx;
    bool isStarted;
    std::thread worker;

    X() : isStarted(false) {}

    void aMethod()
    {
        worker = std::thread(&X::Worker, this);

        std::this_thread::sleep_for(std::chrono::seconds(1));

        {
            std::cout << "signalling worker\n";
            std::unique_lock<std::mutex> lock(mx);
            isStarted = true;
            cv.notify_one();
        }

        worker.join();
        isStarted = false;
    }

    void Worker()
    {
        std::unique_lock<std::mutex> lock(mx);
        std::cout << "worker ready\n";
        cv.wait(lock, [this] { return isStarted; });
        std::cout << "worker started\n";

        std::cout << "worker done\n";
    }
};

int main()
{
    X o;
    o.aMethod();
}

Note that

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top