Я смущен в связи с тем, почему существует lock_guard
. Это:
- Более простой интерфейс, чем
unique_lock
? - Лучшая производительность, чем
unique_lock
? - Что-то еще?
Я смущен в связи с тем, почему существует lock_guard
. Это:
unique_lock
?unique_lock
? lock_guard
может быть реализован с одной единицей состояния: указателем или ссылкой на тип Mutex
, который он заблокировал.
unique_lock
должен удерживать это состояние и знать, заблокирован ли он в настоящий момент, поскольку unique_lock
может иметь Mutex
, который не заблокирован. Это означает, что он должен иметь как минимум bool
дополнительного состояния.
lock_guard
предоставляет нулевую служебную обертку RAII для блокировки/разблокировки при приобретении и выпуске Mutex
. В основном lock_guard
означает, что существует нулевая причина, чтобы избежать использования RAII для обработки блокировок на Mutex
.
unique_lock
может достигать нулевого накладного расхода, если компилятор может убедиться, что вы используете его только так, чтобы lock_guard
можно было использовать (т.е. построить его, а затем уничтожить, не путаясь с ним).
Помимо этих аргументов эффективности, программист, который видит lock_guard
, знает, что он будет длиться до конца области без необходимости изучения кода в области. Программист, который видит unique_lock
, должен проверить все использование переменной, чтобы знать, если это так.
Но выше всего лишь половина причины.
Другая половина причины заключается в том, что большая часть библиотеки потоков для С++ 11 была основана на библиотеках boost
, в которых уже реализована библиотека, зависящая от платформы. Boost имеет как lock_guard
, так и unique_lock
, с почти идентичной семантикой для версий С++ 11.
Итак, когда стандартная библиотека потоков была boost
, и там, где она была перенесена, и никто не удалил их.
Вы почти отвечаете на свой собственный вопрос здесь - 1) и 2) являются и хорошими причинами. std:: lock_guard - это простой объект блокировки. Такие функции, как тайм-аут при обнаружении мьютексов, добавляют к сложности примитива мьютекса, увеличивая время, затрачиваемое на выполнение операции, и вероятность конкуренции за мьютекс. Так зачем платить за то, что вам не нужно?
Если "try_locking" с тайм-аутами или без них - хороший дизайн, это другой вопрос; как отмену потока, сломанный дизайн, который С++ 11 не реализует.