Pthreads: блокировки чтения/записи, обновление блокировки чтения для блокировки записи
Я использую блокировки чтения/записи в Linux, и я обнаружил, что пытается обновить заблокированный объект чтения до блокировок блокировки записи.
то есть.
// acquire the read lock in thread 1.
pthread_rwlock_rdlock( &lock );
// make a decision to upgrade the lock in threads 1.
pthread_rwlock_wrlock( &lock ); // this deadlocks as already hold read lock.
Я прочитал man-страницу, и это довольно специфично.
Вызывающий поток может блокироваться, если на время, когда вызов сделан, он удерживает блокировка чтения и записи (будь то чтение или блокировка записи).
Каков наилучший способ обновления блокировки чтения блокировки записи в этих обстоятельствах. Я не хочу вводить гонку за переменную, которую я защищаю.
Предположительно, я могу создать еще один мьютекс, чтобы включить освобождение блокировки чтения и получение блокировки записи, но тогда я действительно не вижу использования блокировок чтения/записи. Я мог бы просто использовать обычный мьютекс.
спасибо
Ответы
Ответ 1
Что еще, кроме мертвой блокировки, вы хотите в следующем сценарии?
- поток 1 получить блокировку чтения
- поток 2 получить блокировку чтения
- thread 1 попросите обновить блокировку для записи
- thread 2 попросите обновить блокировку для записи
Итак, я бы просто освободил блокировку чтения, приобрел блокировку записи и снова проверил, должен ли я сделать обновление или нет.
Ответ 2
Простейшим и безопасным было бы сделать блокировку записи с момента, когда вы захотите изменить свои данные, а не с того момента, когда вы уверены, что измените его. Я знаю, что это сделает доступ к вашим данным несколько более сериализованным.
Я немного удивился, читая этот вопрос, потому что я даже не считал, что сначала взял блокировку чтения, а затем перешел на блокировку записи. Ну, в другой ситуации могут потребоваться разные подходы.
Ответ 3
Я думаю, вместо использования блокировки чтения/записи pthread вы можете использовать Posix fcntl(). Здесь вы можете обновиться от чтения, чтобы писать без каких-либо проблем. Мы используем его для вставки B-дерева. Как только мы познакомимся с node, где произойдет внедрение, мы обновим его, чтобы записать блокировку. Также, когда нам нужно разделить node, мы обновим блокировку node, ее родителя node и детей от чтения до записи. Поскольку B-tree - это структура данных на основе файлов, она помогает блокировать область файла.