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 - это структура данных на основе файлов, она помогает блокировать область файла.