Разделение файлов между процессами

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

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

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

 только один процесс работает с файлом, выполняя чтение и запись;

 с файлом работает произвольное число процессов, но все они выполняют только чтение.

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

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

Режим доступа определяет, какие операции сам процесс собирается выполнять с файлом. Обычно различают доступ «только для чтения», «только для записи», «для чтения и записи».

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

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

 режим доступа второго процесса не должен противоречить режиму разделения, установленному первым процессом;

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

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

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

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

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