Read-Copy-Update, RCU (Чтение-модификация-запись[уточнить], чтение-копирование при обновлении, чтение — копирование — обновление[1], Прочитать-Скопировать-Обновить[2]) — механизм синхронизации в многопоточных системах. Реализует неблокирующую синхронизацию для всех читателей структуры данных. Запись может производиться параллельно чтению, однако одновременно может быть активен только один писатель.
Основная идея заключается в том, что вместо изменения уже существующих данных, писатель создаёт их копию, меняет её, а затем атомарно обновляет указатель на структуру данных. При этом все читатели, обратившиеся к структуре до обновления, сохраняют доступ к своей устаревшей копии данных, которая останется неизменна. Все же новые читатели получат доступ уже к обновлённой структуре. Чтение в данном случае является критической секцией, допускающей одновременное чтение несколькими потоками, но не разрешающей прерывать работу потока в процессе.
Рассмотрим для примера, как произвести изменение элемента в односвязный список с применением данного механизма синхронизации.
Роль глобального указателя будет выполнять в данном случае указатель на первый элемент. Писателю придётся создать копию всего списка, обновить интересующий его элемент, а затем атомарно обновить глобальный указатель так, чтобы он указывал на первый элемент нового списка. Все читатели, обратившиеся к списку до его обновления, продолжат работать со старой копией, которая останется неизменной. Новые читатели получат доступ уже к новой копии.
Данный метод нельзя назвать эффективным из-за необходимости копировать весь список. Однако если можно гарантировать, что читатели будут работать лишь с одним элементом списка и при переходе к следующему будут обновлять блокировку, то писателю можно оставить необходимость копировать и изменять только интересующий его элемент, после чего он атомарно обновит указатель в предыдущем элементе списка (или указатель на первый элемент).
Добавление элемента в список очень похоже на изменение, однако по причине отсутствия данных, к которым могли иметь доступ читатели во время создания нового элемента, здесь нет нужды следить за тем, когда удалять старую копию данных.
После создания нового элемента и обновления указателя старая копия элемента всё ещё остаётся в памяти, и её нельзя удалить, пока все читатели, имеющие к ней доступ, не разблокируют её. Для этого можно воспользоваться блокирующими механизмами синхронизации. Альтернативным вариантом является учёт того факта, что чтение является критической секцией. Тогда поток-писатель системным вызовом планирует себя поочерёдно после каждого из потоков-читателей. В этом случае все читатели гарантировано пройдут через переключение контекста и значит завершат использование ссылки на устаревшую версию структуры данных.
При использовании алгоритма чтение-модификация-запись каждый поток-читатель не должен делать никаких предположений о том, что произойдёт со структурой данных. Это значит, что сохранение указателя на структуру и использование его за пределами критической секции и даже при входе в новую критическую секцию чтения может привести к ошибке. Весь доступ к структуре данных должен производиться только в критической секции, и поток-читатель при необходимости может скопировать себе данные в этот период, после чего работать уже со своей локальной копией, освободив блокировку и не рискуя при этом попытаться обратиться к уже удалённым потоком-писателем данным.
В операционной системе Linux поддержка RCU присутствует начиная с версии ядра 2.5. Основные функции RCU API:
Также, для защиты от оптимизаций компилятора, меняющих последовательность исполнения инструкций, определены макросы для безопасного получения и обновления указателя на структуру данных rcu_dereference() и rcu_assign_pointer() соответственно.
Происхождение названия связано с тем, что поток-писатель сначала читает (read) структуру данных, затем модифицирует (update) её копию, после чего атомарно записывает указатель на обновлённую (copy) структуру данных.[источник не указан 613 дней]
На некоторых платформах (например, RISC) недоступна данная инструкция. Эквивалентных результатов можно достичь с помощью инструкций:
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .