2015-09-01 5 views
3

Читаю libstdC++ implementation из std::condition_variable::wait_until, вот источник:реализация станд :: condition_variable :: wait_until

template<typename _Clock, typename _Duration> 
    cv_status 
    wait_until(unique_lock<mutex>& __lock, 
    const chrono::time_point<_Clock, _Duration>& __atime) 
    { 
    // DR 887 - Sync unknown clock to known clock. 
    const typename _Clock::time_point __c_entry = _Clock::now(); 
    const __clock_t::time_point __s_entry = __clock_t::now(); 
    const auto __delta = __atime - __c_entry; 
    const auto __s_atime = __s_entry + __delta; 

    return __wait_until_impl(__lock, __s_atime); 
    } 

template<typename _Clock, typename _Duration, typename _Predicate> 
    bool 
    wait_until(unique_lock<mutex>& __lock, 
    const chrono::time_point<_Clock, _Duration>& __atime, 
    _Predicate __p) 
    { 
    while (!__p()) 
     if (wait_until(__lock, __atime) == cv_status::timeout) 
     return __p(); 
    return true; 
    } 

Второй вызов функции первой функции в loop.which будет делать операцию синхронизации часов .So, если мы вызываем вторую функцию, операция синхронизации может выполняться много раз. Нужно ли синхронизировать часы каждый раз? Я думаю, что код можно улучшить синхронизирующими часами только один раз во второй функции. Я прав?

ответ

0

Да, и нет.

Да, этот код может быть оптимизирован, чтобы не манипулировать time_point с, когда он петли. Однако я не уверен, что это действительно необходимо.

Рассмотрите, что делает заданный цикл wait_until.

Когда notified, он проверяет предикат, чтобы увидеть, есть ли работа.

  1. Если предикат возвращает истину, то есть условие защищено переменным условие истинно, wait_until возвращает true.
  2. Если истечет таймаут, wait_until возвращает значение предиката, который обычно будет false (в противном случае мы ожидали, что condition_variable был бы уведомлен).

Это оставляет только один случай, когда петля на самом деле петли: Когда condition_variable уведомлен, но предикат возвращает false.

Это известный как spurious wakeup и вряд ли типичный случай, поэтому на самом деле его не стоит оптимизировать.

0

Я думаю, что вы правы. С другой стороны, предположения для использования wait_until обычно состоят в том, что событие будет происходить только редко, а предикат возвращается true для всех, кроме нескольких случаев нежелательных пробуждений. Таким образом, накладные расходы на повторную синхронизацию часов должны быть минимальными. Помните также, что в этом случае поток должен был быть разбужен и выгружен уже, что, вероятно, дороже, чем запрос на часы.

+0

Не могли бы вы объяснить: «Помните также, что в этом случае поток нужно было разбудить и пронести по нему уже, что, вероятно, дороже, чем запрос на часы». Я просто могу понять. – prehistoricpenguin

+0

@prehistoricpenguin поток нужно было разбудить, чтобы продолжить выполнение, которое, вероятно, дороже, чем два вызова часов - дело в том, что это не стоит оптимизировать для общего случая. см. также ответ Шона для более подробной информации о обычных предположениях для wait_until. – BeyelerStudios

+0

@ BeyerStudios, Спасибо за объяснение, получил его – prehistoricpenguin

Смежные вопросы