Использование timed_wait от boost? - PullRequest
1 голос
/ 27 марта 2012

Я пытаюсь использовать timed_wait от наддува. Теперь я на самом деле не совсем уверен, как это сделать.

Цель всего этого - определить его состояние. В приведенном ниже коде вызывается функция getStatus(). Эта функция асинхронная, и если все прошло правильно, она вызывает специальную функцию обратного вызова, чтобы указать, что все в порядке. Если он не вызывает обратный вызов во времени (поэтому происходит таймаут), я знаю, что что-то пошло не так.

Так вот пример кода:

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()
{
/* ... */
}

Итак, как вы можете видеть, я не знаю, как правильно «добавить» обратный вызов в мой timed_wait. На самом деле я не понимаю, как это будет работать, поскольку я ожидаю, что мой Callback будет вызываться из моего асинхронного потока, а не из самого timed_wait? (Асинхронный поток должен сигнализировать, что все прошло хорошо)

Я также заглянул в документацию по ускорению 1014 *, но это не могло мне помочь.

По второму вопросу: мой мьютекс в этом примере всегда заблокирован?

1 Ответ

3 голосов
/ 27 марта 2012

Относительно вашего второго вопроса: мьютекс заблокирован во всей функции checkStatus , за исключением во время выполнения timed_wait.И это ключ.

Я не уверен, что вы намерены сделать с myCallback.Но для проверки статуса я бы добавил члена статуса к myClass, установил его в getStatus и проверил в ветке else timed_wait.Пример:

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();
}

Надеюсь, теперь все понятнее.Может быть, вы можете интегрировать свою функцию обратного вызова в этом подходе.Также вам следует рассмотреть возможность отмены фонового потока в случае тайм-аута, чтобы избежать условий гонки.

Редактировать: Обратите внимание, что переменная условия должна быть членом, чтобы уведомить его о завершенииасинхронная операция.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...