Что такое замок для повторного входа и концепция в целом?
Я всегда путаю. Кто-нибудь объяснит, что Reentrant означает в разных контекстах? И почему вы хотите использовать реентерабельность против нереентерабельности?
скажем, pthread (posix) блокирующие примитивы, они повторно вступают или нет? Каких подводных камней следует избегать при их использовании?
является ли мьютекс re-entrant?
3 ответов:
блокировка повторного входа
реентерабельная блокировка-это та, где процесс может требовать блокировки несколько раз, не блокируя себя. Это полезно в ситуациях, когда нелегко отслеживать, захватили ли вы уже замок. Если блокировка не является повторной, вы можете захватить блокировку, а затем заблокировать, когда вы снова ее захватите, эффективно блокируя свой собственный процесс.
Reentrancy в общем случае является свойством кода, где он не имеет центрального изменяемого состояние, которое может быть повреждено, если код был вызван во время выполнения. Такой вызов может быть выполнен другим потоком, или он может быть выполнен рекурсивно путем выполнения, происходящим из самого кода.
Если код полагается на общее состояние, которое может быть обновлено в середине его выполнения, он не является повторно входящим, по крайней мере, если это обновление может его сломать.
вариант использования для блокировки повторного входа
A (несколько общий и надуманный) пример приложения для блокировки повторного входа может быть:
У вас есть некоторые вычисления с использованием алгоритма, который пересекает граф (возможно, с циклами в нем). Обход может посетить один и тот же узел более одного раза из-за циклов или из-за нескольких путей к одному и тому же узлу.
структура данных подлежит параллельному доступу и может быть обновлена по какой-то причине, возможно, другим потоком. Вы должны быть в состоянии блокировка отдельных узлов для борьбы с потенциальным повреждением данных из-за условий гонки. По какой-то причине (возможно, производительность) вы не хотите глобально блокировать всю структуру данных.
вы не можете сохранить полную информацию о том, какие узлы вы посетили, или вы используете структуру данных, которая не позволяет быстро ответить на вопросы "был ли я здесь раньше".
примером такой ситуации может быть простая реализация Алгоритм Дейкстры с приоритетной очередью реализован в виде двоичной кучи или поиска по ширине с использованием простого связанного списка в качестве очереди. В этих случаях сканирование очереди для существующих вставок является O (N), и вы не можете сделать это на каждой итерации.в этой ситуации отслеживание того, какие замки вы уже приобрели, стоит дорого. Предполагая, что вы хотите сделать блокировку на уровне узла, механизм блокировки повторного входа устраняет необходимость указывать, нужно ли вы уже посещали узел раньше. Вы можете просто слепо заблокировать узел, возможно, разблокировав его после того, как вы вытащите его из очереди.
Re-entrant мьютексы
простой мьютекс не является повторным, так как только один поток может быть в критической секции в данный момент времени. Если вы схватите мьютекс, а затем попытаетесь схватить его снова, у простого мьютекса недостаточно информации, чтобы сказать, кто держал его ранее. Для этого рекурсивно вам нужен механизм, где каждый поток имел токен, чтобы вы могли сказать, кто схватил мьютекс. Это делает механизм мьютекса несколько дороже, так что вы не можете сделать это во всех ситуациях.
IIRC API потоков POSIX предлагает возможность повторного входа и не повторного входа мьютексов.
блокировка повторного входа позволяет вам написать метод
Mчто ставит блокировку на ресурсAа потом позвонитеMрекурсивно или из кода, который уже содержит блокировку наA.С блокировкой без повторного входа вам понадобится 2 версии
M, тот, который блокирует и тот, который не делает, и дополнительная логика, чтобы вызвать правильный.
Реентерабельная блокировка очень хорошо описана в этом учебник.
пример в учебнике гораздо менее надуман, чем в ответе о прохождении графика. Реентерабельная блокировка полезна в очень простых случаях.
Comments