Ядро Linux в комментариях

       

Write_lock


Выдача сигнала о том, что какой-то процесс хочет приобрести блокировку записи: проверка и установка знакового бита блокировки для обеспечения отрицательного значения члена lock.

Если знаковый бит уже установлен, какой-то еще процесс владеет блокировкой записи; макрокоманда write_lock переходит вперед к строке (которая, как и прежде, находится в другой секции ядра).

Больше никто не пытался получать блокировку записи, но процессы чтения все еще могут существовать. Поскольку знаковый бит установлен, никакой иной процесс чтения не сможет приобрести эту блокировку чтения, но макрокоманда write_lock все еще обязана ждать, пока не исчезнут все прочие существующие процессы чтения. Она начинает работу с проверки того, установлен ли какой-либо из 31 бита в младших разрядах, что может служить свидетельством того, что значение lock перед этим было положительным. Если нет, то значение lock перед инверсией знакового бита было равно 0, а это значит, что нет процессов чтения, следовательно, данный процесс записи может безопасно продолжить свою работу, поэтому управление просто переходит дальше. Однако, если среди 31 бита в младших разрядах был установлен хоть один бит, это значит, что имеются процессы чтения, поэтому макрокоманда write_lock переходит к строке , чтобы там ожидать завершения их работы.

Данный процесс является единственным процессом записи, но есть еще процессы чтения. Макрокоманда write_lock на данный момент очищает знаковый бит (она снова захватит его позднее). Любопытно отметить, что эти манипуляции со знаковым битом не нарушают правильности операций процессов чтения с членом lock. Рассмотрим в качестве примера приведенную ниже последовательность событий:

  • Два процесса чтения увеличивают значение lock; теперь шестнадцатиричное значение lock равно 0x00000002.
  • Потенциальный процесс записи устанавливает знаковый бит; теперь lock имеет значение 0x80000002.
  • Один из процессов чтения уходит; теперь lock имеет значение 0x80000001.
  • Процесс записи обнаруживает, что не все оставшиеся биты равны 0; это значит, что есть еще процессы чтения. Таким образом, процесс записи все еще не может приобрести блокировку записи и поэтому очищает знаковый бит; теперь значение lock равно 0x00000001.
  • Таким образом, попытки чтения и записи могут чередоваться в любом порядке, не влияя на правильность результата.

    Циклическое выполнение в ожидании, пока значение счетчика не упадет до 0, то есть в ожидании, пока не уйдут все процессы чтения. В действительности, нулевое значение показывает, что не только ушли все процессы чтения, но и никто иной еще не приобрел блокировку записи.

    По-видимому, ушли все процессы чтения и записи; макрокоманда write_lock начинает все сначала и снова захватывает блокировку записи.



    Содержание раздела