2017-02-13 7 views
1

Ниже приведен исходный код в файле заголовка conditional_variable из C++ 5.2.1. Интересно, есть ли проблема в первую ждать, где пока Тестирование не находится в критической секции __lock разбудила из ждать снова.Является ли это ошибкой в ​​C++ conditional_variable?

template<typename _Lock, typename _Predicate> 
void wait(_Lock& __lock, _Predicate __p) { 
    while (!__p()) 
     wait(__lock); 
} 

template<typename _Lock> 
void wait(_Lock& __lock) { 
    shared_ptr<mutex> __mutex = _M_mutex; 
    unique_lock<mutex> __my_lock(*__mutex); 
    _Unlock<_Lock> __unlock(__lock); 
    // *__mutex must be unlocked before re-locking __lock so move 
    // ownership of *__mutex lock to an object with shorter lifetime. 
    unique_lock<mutex> __my_lock2(std::move(__my_lock)); 
    _M_cond.wait(__my_lock2); 
} 
+0

Посмотрите, что делает '_Unlock'. – GManNickG

+0

он просто вызывает разблокировку 'unplicit _Unlock (_Lock & __lk): _M_lock (__ lk) {__lk.unlock(); } ' – uqb

+1

А как насчет деструктора? – GManNickG

ответ

1

Не ошибка. Когда оценивается !__p(), мьютекс в __lock якобы по-прежнему заблокирован текущей нитью.

Я полагаю, код представлен из libstdC++.

+0

Когда верхний * wait * вызывается пользователем, * * блокировка * сохраняется, но * __ блокировка * высвобождается в бутылка * дождитесь * до фактической блокировки, и * __ lock * не будет повторно заблокирован, когда поток проснется, чтобы снова оценить __p(). Что-то не так? – uqb

+0

В источнике libstdC++ я обнаружил деструктор '_Unlock', пытающийся заблокировать мьютекс. – cshu