В чем заключается работа std::unique_lock при использовании с std::conditional_variable::wait()

Я совершенно запутался с необходимостью std::unique_lock когда ждать std::conditional_variable, Поэтому я изучаю код библиотеки в VS 2013 и запутываюсь. Вот как std::conditional_variable::wait() внедрено:

void wait(unique_lock<mutex>& _Lck)
    {   // wait for signal
    _Cnd_waitX(&_Cnd, &_Lck.mutex()->_Mtx);
    }

Это какая-то шутка? Завернуть мьютекс в unique_lock и ничего не делать, кроме как вернуть его позже? Почему бы просто не использовать мьютекс в списке параметров?

2 ответа

Идея в том, что когда вы звоните wait, вы хотите получить сигнал при изменении значения некоторой переменной (отсюда condition_variable). Теперь, поскольку вы обращаетесь к рассматриваемой переменной из нескольких потоков (иначе вам не понадобится синхронизация), она, вероятно, будет защищена мьютексом. Таким образом, пока вы ждете изменения переменной, вам придется отказаться от мьютекса, а когда вы получите сигнал, вы должны снова его получить. Это то, что эта функция делает для вас.

Проблема в том, что когда вы просыпаетесь после получения сигнала, вам нужно уже заблокировать мьютекс. Если вы попытаетесь заблокировать мьютекс после пробуждения по сигналу, вы получите состояние гонки. С другой стороны, ожидание условной переменной не может заблокировать этот мьютекс сам по себе, так как он не сможет правильно вернуть блокировку вам, и обычно вы должны заблокировать мьютекс, прежде чем вы все равно попадете в ожидание.

Другие вопросы по тегам