POSIX довольно ясно показывает, что в pthread_rwlock_rdlock():
Вызывающий поток может заблокироваться, если во время выполнения вызова он удерживает блокировку записи.
и в pthread_rwlock_wrlock():
Вызывающий поток может заблокироваться, если во время выполнения вызова он удерживает блокировку чтения-записи (будь то блокировку чтения или записи).
Я подозреваю, что это делается для простоты.
Возможность повышать блокировку чтения до блокировки записи выглядит полезной, но (к сожалению) это не так. Рассмотрим структуру данных «индекс», в которой «поиск» автоматически добавляет значения, которые не найдены: когда поиск не находит заданное значение, было бы неплохо активировать блокировку чтения и продолжить добавление значения в индекс. на том основании, что за это время ничего не могло измениться. К сожалению, это не сработает: рассмотрим два поиска, которые выполняются одновременно, и обоим нужна блокировка записи :-( Итак, заставляя программиста снять блокировку чтения и получить блокировку записи, по крайней мере, становится очень ясно, что это происходит.
Имейте в виду, если у «поиска по индексу» есть проблема, если он может удерживать «n» блокировок чтения в тот момент, когда он решает, что ему нужна блокировка записи, особенно если он не может узнать, что такое «n»: - (Было бы неплохо, по крайней мере, иметь возможность обнаружить 'n', запросив rwlock !
Попутно я обнаружил, что FreeBSD имеет:
rw_try_upgrade (структура rwlock *rw)
Попытка обновить одну общую блокировку до монопольной блокировки. Текущий поток должен удерживать общую блокировку rw. Это будет успешным только в том случае, если текущий поток удерживает единственную общую блокировку на rw, и он удерживает только одну общую блокировку. Если попытка увенчается успехом, rw_try_upgrade() вернет ненулевое значение, и текущий поток будет удерживать монопольную блокировку. Если попытка не удалась, rw_try_upgrade() вернет ноль, а текущий поток по-прежнему будет удерживать общую блокировку.
... но я отмечаю все оговорки о том, когда это действительно что-то сделает!
К вопросу о понижении блокировки записи до блокировки чтения...
... семантика довольно ясна, если нет ожидающих блокировок записи. Однако, если есть один или несколько ожидающих авторов, все не так просто.
В настоящее время программист вынужден снять блокировку записи и получить блокировку чтения, и совершенно ясно, что происходит.
Если бы операция «понижения» была определена как атомарная «запись-разблокировка/чтение-блокировка», то это могло бы позволить читателям опережать любых ожидающих записи или могло бы позволить читателям войти только в том случае, если нет ожидающих записи — второй кажется мне лучшим вариантом. Преимущество «понижения» состоит в том, что после понижения состояние больше не изменилось — я полагаю, это полезно.
Если бы pthread_rwlock_rdlock()
при удержании блокировки записи было определено как «понижение», тогда нужно было бы четко указать, сколько уровней блокировки это приведет. Если результатом будут две блокировки, будет снята вторая (блокировка чтения) повторно получить первый (блокировка записи) или оставить его заблокированным для чтения? [Если бы было возможно «обновить» блокировку чтения до блокировки записи, как определить для работы произвольные последовательности блокировки чтения/блокировки записи/обновления/понижения/разблокировки?]
person
Community
schedule
10.07.2014