简体   繁体   中英

Use of timed_wait from boost?

I am trying to use the timed_wait from boost. Now I am actually not quite sure how to do this.

The purpose of the whole thing is to determine it's state. In the code below a function getStatus() is called. This function is async and if everything went right it calls a specific callback function to indicate that everything is allright. If it not calls the callback in time ( so timeout occurs ) I know something went wrong.

So here is the example code:

void myClass::checkStatus()
{
    boost::mutex::scoped_lock lock(m_Mutex);
    boost::condition_variable cond;
    while(true)
    {
        getStatus();  // Async Call to get the actual status
        if(!cond.timed_wait(lock,boost::posix_time::milliseconds(3000),/* Callback */))
        { 
           // Timeout
        }
        else
        {
            // OK 
        }
    }
}
bool myClass::myCallback()
{
/* ... */
}

So, as you can see, I don't know how to appropriately "add" the callback to my timed_wait. Actually I don't actually get it how it will work since I expect my Callback to be called from my async thread and not from the timed_wait itself? ( The async thread needs to signalize that everything went well )

I also looked into the Boost Documentation but it couldn't help me much more.

On a second question: Is my mutex in this example always locked..?

Regarding your second question: The mutex is locked in the entire checkStatus function except during the execution of timed_wait . And that is the key.

I'm not sure what you intention with myCallback is. But to check the status I would add a status member to myClass , set it in getStatus and check it in the else branch of the timed_wait . An example:

boost::condition_variable m_cond;

void myClass::checkStatus()
{
    boost::mutex::scoped_lock lock(m_Mutex);

    while(true)
    {
        getStatus();  // Async Call to get the actual status
        if(!m_cond.timed_wait(lock,boost::posix_time::milliseconds(3000),/* Callback */))
        { 
           // Timeout
        }
        else
        {
            //check status
            if (m_status == STATUS_1)
            {
                // handle STATUS_1
            }
            else if (m_status == STATUS_2)
            {
                // handle STATUS_2
            }
         }
    }
}

void getStatus()
{
    boost::thread myThread(myWorkerFunc);  
}

void myWorkerFunc()
{
    // do a long running operation to get the status
    int status = retrieveStatusSomehow();

    // lock the same mutex that you used for the condition variable
    boost::mutex::scoped_lock lock(m_Mutex);

    // assign the status to member
    m_status = status;

    // notify the condition to wake up
    m_cond.notify_all();
}

I hope it is clearer now. Maybe you can integrate your callback function in this approach. Also you should consider to cancel the background thread in case of a timeout to avoid race conditions.

Edit: Note that the condition variable must be a member to notify it about the end of the async operation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM