Friday, May 18th

Last update12:13:00 PM GMT

Вы находитесь на: FreeBSD Обзор системы ввода/вывода Блокировка дескриптора файла

Блокировка дескриптора файла

На ранних UNIX-системах не было обеспечения блокировки файлов. Процессам, которым нужно было синхронизировать доступ к файлу, приходилось использовать отдельный файл блокировки (lock file). Процесс пытался создать файл блокировки. Если попытка была успешной, процесс мог продолжить обновление; если попытка завершалась неудачей, процесс должен был ждать, а затем пытаться снова. У этого механизма было три недостатка.

1. Процессы потребляли время процессора в цикле, пытаясь создать блокировки.

2. Блокировки, оставшиеся разбросанными вокруг в результате сбоя системы, приходилось удалять (обычно в командном сценарии запуска системы).

3. Процессам, работающим от имени специального пользователя администратора системы, суперпользователя, всегда разрешалось создавать файлы, поэтому они были вынуждены использовать другой механизм.

Хотя все эти проблемы можно решить, решения не являются простыми, поэтому в 4.2BSD был добавлен механизм для блокировки файлов.

Наиболее общие схемы блокировки позволяют нескольким процессам одновременно обновлять файл. Некоторые из этих методик обсуждаются в Peterson [1983]. Более простой методикой является упорядочивание доступа к файлу с помощью блокировок. Для стандартных системных приложений достаточно механизма, который блокирует на уровне файла. Поэтому 4.2BSD и 4.3BSD предоставляли лишь быстрый механизм блокировки всего файла. Семантика этих блокировок включала возможность наследования блокировок порожденным процессом и освобождение блокировок лишь при последнем закрытии файла.

Некоторым приложениям требуется возможность блокировки участков файла. Средства блокировки, поддерживающие степень детализации на уровне байтов, хорошо поняты. К сожалению, они недостаточно мощны, чтобы использоваться системами баз данных, которым требуются вложенные иерархические блокировки, но достаточно сложны, чтобы требовать больших и громоздких реализаций по сравнению с более простыми блокировками всего файла. Поскольку стандарт POSIX предоставляет блокировки диапазонов байтов, разработчики неохотно добавили их к BSD. Семантика блокировок диапазонов байтов пришла из первоначальной реализации блокировок в System V, которая включала освобождение всех блокировок, удерживаемых процессом для файла, каждый раз, когда для дескриптора, ссылающегося на файл, выполнялся системный вызов close. Блокировки 4.2BSD для всего файла удаляются лишь при последнем закрытии. Проблема с семантикой POSIX в том, что приложение может заблокировать файл, затем вызвать библиотечную процедуру, которая открывает, читает и закрывает заблокированный файл. Вызов библиотечной процедуры даст неожиданный эффект освобождения блокировки, удерживаемой приложением. Другая проблема в том, что файл должен быть открыт на запись, чтобы получать исключительную блокировку. Процесс, у которого нет разрешения для открывания файла для записи, не может получить исключительную блокировку для этого файла. Чтобы избежать этих проблем, все еще оставаясь совместимой с POSIX, FreeBSD предоставляет отдельные интерфейсы для блокировок диапазонов байтов и блокировок файлов целиком. Блокировки диапазонов байтов следуют семантике POSIX; блокировки файлов целиком следуют традиционной семантике 4.2BSD. Эти два вида блокировок могут использоваться одновременно; они будут соответствующим образом упорядочены друг относительно друга.

Как блокировки всего файла, так и блокировки диапазонов байтов используют одну и ту же реализацию; блокировки всего файла реализованы в виде блокировки диапазона всего файла. Ядро управляет отличающейся между этими двумя реализациями семантикой, применяя блокировки диапазонов байтов к процессам, тогда как блокировки всего файла применяются к дескрипторам. Поскольку дескрипторы разделяются с порожденными процессами, блокировки всего файла наследуются. Поскольку порожденный процесс получает свою собственную структуру процесса, блокировки диапазонов байтов не наследуются. Семантика последнего закрытия против семантики каждого закрытия является небольшим куском кода особого случая в процедуре закрытия, который проверяет, является ли нижележащий объект процессом или дескриптором. Он освобождает блокировки при каждом вызове, если блокировка связана с процессом, и лишь когда счетчик ссылок падает до нуля, если блокировка связана с дескриптором.

Схемы блокировок можно классифицировать в соответствии со степенью их обязательности. Говорят, что схема, при которой блокировки приводятся в исполнение для каждого процесса без возможности выбора, использует обязательные (mandatory) блокировки, тогда как схема, при которой блокировки приводятся в исполнение лишь для тех процессов, которые их запрашивают, использует необязательные (advisorty) блокировки. Очевидно, необязательные блокировки эффективны лишь тогда, когда все программы, получающие доступ к файлу, используют схему блокировки. При обязательных блокировках в ядре должна быть реализована некоторая политика аннулирования. При необязательных блокировках эта политика оставлена пользовательским программам. В системе FreeBSD программам с привилегией суперпользователя разрешено аннулировать любую схему защиты. Поскольку многие из программ, которым нужно использовать блокировки, должны также работать от имени суперпользователя, 4.2BSD реализовала обязательные блокировки вместо создания дополнительной схемы защиты, которая была бы несовместимой с философией UNIX или не могла использоваться привилегированными программами. Использование обязательных блокировок перешло в спецификацию POSIX блокировок диапазонов байтов и осталось в FreeBSD.

Средства блокировки файлов FreeBSD дают взаимодействующим программам возможность применять обязательные разделяемые или исключительные блокировки на диапазоны байтов внутри файла. Лишь один процесс может иметь исключительную блокировку на диапазон байтов, тогда как разделяемых блокировок может быть несколько. Разделяемая и исключительная блокировки не могут присутствовать для диапазона байтов в одно и то же время. Если запрошена любая блокировка, в то время когда другой процесс удерживает исключительную блокировку, или когда запрошена исключительная блокировка, когда другой процесс удерживает любую блокировку, запрос блокировки будет заблокирован до тех пор, пока неблокировка не сможет быть получена. Поскольку разделяемые и исключительные блокировки являются лишь необязательными, даже если процесс получил блокировку на файл, другой процесс может получить доступ к файлу, если он игнорирует механизм блокировки.

Поскольку между созданием и блокированием файла нет состязания, блокировка может быть запрошена как часть открытия файла. Когда процесс открыл файл, он может манипулировать блокировками без необходимости закрыть и повторно открыть файл. Эта особенность полезна, например, когда процесс хочет применить разделяемую блокировку для считывания информации, чтобы определить, нужно ли обновление, а затем использовать исключительную блокировку и обновить файл.

Запрос блокировки заставит процесс заблокироваться, если блокировка не может быть получена немедленно. В отдельных случаях это блокирование является неподходящим. Например, процессу, который хочет лишь проверить, присутствует ли блокировка, потребовался бы отдельный механизм для получения этой информации. Поэтому процесс может обозначить, что его запрос блокировки должен вернуть ошибку, если блокировка не может быть получена немедленно. Возможность запрашивать блокировки условно полезна процессам демонов, которые хотят обслуживать область спулинга. Если первый экземпляр демона блокирует каталог, в котором происходит спулинг, следующие процессы демонов легко могут проверить, существуют ли активные демоны. Поскольку блокировки существуют, лишь пока существует блокирующий процесс, блокировки никогда не могут оставаться активными после завершения процесса или при аварии системы.

Реализация блокировок сделана на основе отдельных файловых систем. Сетевая файловая система должна координировать блокировки с главным менеджером блокировок, который обычно расположен на сервере, экспортирующем файловую систему. Запросы блокировок клиентов должны посылаться менеджеру блокировок. Менеджер блокировок выносит решения по запросам блокировок от процессов, работающих на его сервере, и от различных клиентов, для которых экспортируется файловая система. Наиболее сложной операцией для менеджера блокировок является восстановление состояния блокировки, когда клиент или сервер перезагружаются или становятся отделенными от остальной сети.


Похожие:
Еще по теме:
Советуем прочитать:

Сейчас 65 гостей онлайн

Реклама на сайте: