Блокировка чтения-записи


Блокировка чтения-записи — механизм синхронизации, разрешающий одновременное общее чтение некоторых разделяемых данных либо их эксклюзивное изменение, разграничивая таким образом блокировки на чтение и на запись между собой[1]. Механизм призван решить классическую задачу о читателях-писателях, в которой некоторый объект одновременно читается и пишется конкурентными задачами[2].

В отличие от мьютексов блокировки чтения-записи отдельно учитывают чтение данных и отдельно — запись, разрешая обращение к данным, если они в это время не изменяются. Мьютексы же допускают только эксклюзивный доступ к данным[1]. Однако встречаются разделяемые мьютексы, предоставляющие помимо эксклюзивной блокировки общую, позволяющую совместно владеть мьютексом, если нет эксклюзивного владельца[3]. По своей сути разделяемые мьютексы являются блокировками чтения-записи, но именуются мьютексами.

В общем случае блокировки чтения-записи решают ту же задачу, что и мьютексы, и могут быть ими заменены, причиной же появления механизма блокировок чтения-записи является повышение эффективности взаимного исключения при раздельном чтении и записи[4]. Блокировки чтения-записи являются более предпочтительными, чем мьютексы, в случаях, когда обращения к данным происходят намного чаще, чем их запись. В этом случае читающие задачи не будут блокироваться большую части времени, лишь иногда блокируясь при изменениях объекта. Приоритет между пишущими и читающими задачами часто отдаётся пишущим задачам, чтобы избежать ресурсного голодания пишущих задач[1].

Проблема читателей и писателей возникает в любой ситуации, когда требуется одновременное чтение и изменение структуры данных, файловой системы или базы данных конкурентными задачами. Чтение неизменных данных может осуществляться одновременно множеством задач, однако если в это время будет происходить изменение данных, параллельное их чтение может привести к получению частично изменённых данных, то есть испорченных[2].

Решение задачи является асимметричным и предполагает разделение блокировки на чтение и на запись. Изменение данных допускается лишь эксклюзивное, то есть только одна задача может единовременно захватывать блокировку на запись, если только не захвачена блокировка на чтение. Чтение данных может осуществляться многими задачами, поэтому блокировку на чтение могут захватить одновременно сколько угодно задач, если только не захвачена блокировка на запись. То есть критические секции записи и чтения не могут исполняться параллельно, но критические секции чтения — могут[2].