boost:: уникальный замок против boost:: Lock guard
Я не очень хорошо понимаю разницу между этими двумя классами замок.
В документации boost сказано:boost::unique_lock
не реализует блокировку автоматически.
означает ли это, что основная разница между unique_lock
и lock_guard
заключается в том, что с unique_lock
мы должны явно вызвать
5 ответов:
во-первых, чтобы ответить на ваш вопрос. Нет, вам не нужно вызывать блокировку на unique_lock. Смотрите ниже:
unique_lock - это только класс блокировки с большим количеством функций. В большинстве случаев lock_guard будет делать то, что вы хотите, и будет достаточно.
В unique_lock имеет больше возможностей, чтобы предложить вам. Например, приуроченное ожидание, если вам нужен тайм-аут или если вы хотите отложить блокировку до более поздней точки, чем построение объекта. Так это сильно зависит от того, что вы хотите сделать. Кстати: следующие фрагменты кода делают то же самое.boost::mutex mutex; boost::lock_guard<boost::mutex> lock(mutex);
boost::mutex mutex; boost::unique_lock<boost::mutex> lock(mutex);
первый может быть использован для синхронизации доступа к данным, но если вы хотите использовать переменные состояния нужно перейти на второй.
в настоящее время лучший голосованный ответ хорош, но он не прояснил мои сомнения, пока я не копнул немного глубже, поэтому решил поделиться с людьми, которые могут быть в одной лодке.
во-первых, оба
lock_guard
иunique_lock
следует шаблону RAII, в простейшем случае использования замок приобретается во время строительства и автоматически разблокируется во время разрушения. Если это ваш вариант использования, то вам не нужна дополнительная гибкостьunique_lock
иlock_guard
будет более эффективным.в ключевое различие между обоими является
unique_lock
экземпляр не должен всегда владеть мьютексом, с которым он связан, находясь вlock_guard
Он владеет мьютексом. Это значитunique_lock
должен быть дополнительный флаг, указывающий, владеет ли он блокировкой, и еще один дополнительный метод " owns_lock ()", чтобы проверить это. Зная это, мы можем объяснить все дополнительные преимущества, которые эти флаги приносят с накладными расходами этих дополнительных данных, которые нужно установить и проверить
- замок не должен приниматься прямо на строительстве, вы можете передать флаг
std::defer_lock
во время его строительства, чтобы сохранить мьютекс разблокирован во время строительства.- мы можем разблокировать его до завершения функции и не обязательно ждать, пока деструктор выпустит его, что может быть удобно.
- вы можете передать право собственности на замок из функции, это подвижные, а не копировать.
- он может использоваться с условными переменными, так как это требует блокировки мьютекса, условие проверено и разблокировано во время ожидания условия.
их реализация может быть найдена в разделе путь .../ повышение / поток / замки.ГЭС - и они сидят просто один рядом с другим:) короче говоря:
lock_guard это короткий простой служебный класс, который блокирует мьютекс в конструкторе и разблокирует в деструкторе, не заботясь о деталях.
unique_lock немного сложнее, добавляя довольно много функций, но он по-прежнему автоматически блокируется в конструкторе. Это называется unique_lock, потому что он вводит понятие" lock ownership " (см. Метод owns_lock ()).
если вы привыкли к
pthreads(3)
:
boost::mutex
=pthread_mutex_*
boost::unique_lock
=pthread_rwlock_*
используется для получения блокировки записи / исключения (т. е.pthread_rwlock_wrlock
)boost::shared_lock
=pthread_rwlock_*
используется для получения чтения / общих блокировок (т. е.pthread_rwlock_rdlock
)да
boost::unique_lock
иboost::mutex
функция аналогично, но aboost::mutex
обычно является более легким мьютексом веса для приобретения и выпуска. Что сказалshared_lock
С уже приобретенным замком быстрее (и позволяет параллелизм), но это сравнительно дорого, чтобы получитьunique_lock
.вы должны заглянуть под обложки, чтобы увидеть детали реализации, но это суть предполагаемых различий.
говоря о производительности: вот умеренно полезное сравнение задержек:
http://www.eecs.berkeley.edu/%7Ercs/research/interactive_latency.html
было бы неплохо, если бы я / кто-то мог сравнить относительная стоимость различных примитивов pthread_*, но в последний раз я смотрел,
pthread_mutex_*
было ~25us, тогда какpthread_rwlock_*
было ~20-100us в зависимости от того, была ли уже приобретена блокировка чтения (~10us) или нет (~20us) или писатель (~100us). Вам нужно будет проверить, чтобы подтвердить текущие цифры, и я уверен, что это очень специфично для ОС.