Операционная система UNIX
Шрифт:
Более старые версии UNIX используют статическую таблицу дескрипторов, которая целиком хранится в u-area. Номер дескриптора является индексом этой таблицы. Таким образом, размер таблицы, которая обычно содержит 64 элемента, накладывает ограничение на число одновременно открытых процессом файлов. В современных версиях таблица размещается динамически и может увеличиваться при необходимости. Следует, однако, иметь в виду, что и в этом случае максимальное число одновременно открытых файлов регламентируется пределом
Содержимое таблицы дескрипторов процесса можно посмотреть с помощью утилиты crash(1M). Команда user
Файловая таблица
Поля файлового дескриптора
Каждый элемент файловой таблицы содержит информацию, необходимую для управления работой с файлом. Если несколько процессов открывают один и тот же файл, каждый из них получает собственный элемент файловой таблицы, хотя все они будут работать с одним и тем же файлом. Важнейшие поля элемента файловой таблицы приведены ниже:
Поле | Описание |
---|---|
f_flag | Флаги, указанные при открытии файла (системные вызовы open(2), creat(2)). Каждая операция с файлом проверяется на допустимость согласно указанным режимам. Другими словами, если процесс открыл файл только для чтения (флаг FREAD ), ему будет отказано в операции записи, даже если он имеет на это необходимые права доступа. |
FREAD | Файл открыт только для чтения. То же, что и O_RDONLY при открытии файла. |
FWRITE | Файл открыт только на запись. То же, что и O_WRONLY при открытии файла. |
FAPPEND | Режим добавления. Перед началом операции записи файловый указатель будет установлен в конец файла. То же, что и O_APPEND при открытии файла. |
FNONBLOCK , FNDELAY | Возврат без блокирования. Системный вызов не будет ожидать завершения операции. То же, что и O_NONBLOCK или O_NDELAY при открытии файла. |
FSYNC | Обеспечить синхронизацию с соответствующими дисковыми структурами для метаданных и данных файла при совершении операции записи. То же, что и O_SYNC при открытии файла. |
FDSYNC | Обеспечить
синхронизацию с соответствующими дисковыми структурами только для данных файла при совершении операции записи. То же, что и O_DSYNC при открытии файла. |
FRSYNC | Совместно с флагами FSYNC и FDSYNC определяет процесс синхронизации для соответствующих компонентов файла при операции чтения. |
f_count | Число файловых дескрипторов, адресующих данный элемент файловой таблицы. Один и тот же элемент файловой таблицы может совместно использоваться при дублировании дескрипторов с помощью системного вызова dup(2) или в результате fork(2). |
f_vnode | Указатель на виртуальный индексный дескриптор файла. |
f_offset | Текущее смещение в файле. Начиная с этого места будет произведена следующая операция чтения или записи. |
Для иллюстрации обсуждения продолжим работу с утилитой crash(1M). С помощью команды user в предыдущем разделе были получены адреса элементов файловой таблицы для стандартного ввода (fd=0), вывода (fd=1) и вывода сообщений об ошибках (fd=2). Заметим, что все они указывают на один и тот же элемент. С помощью команды file исследуем его содержимое:
Поскольку это специальный файл устройства (об этом свидетельствует поле TYPE элемента файловой таблицы), поле
Поле
– i 317329
В результате мы определили имя специального файла устройства (в данном случае — это псевдотерминал), на которое производится ввод и вывод командного интерпретатора.
Блокирование доступа к файлу
Традиционно архитектура файловой подсистемы UNIX разрешает нескольким процессам одновременный доступ к файлу для чтения и записи. Хотя операции записи и чтения, осуществляемые с помощью системных вызовов read(2) или write(2), являются атомарными, в UNIX по умолчанию отсутствует синхронизация между отдельными вызовами. Другими словами, между двумя последовательными вызовами read(2) одного процесса другой процесс может модифицировать данные файла. Это, в частности, может привести к несогласованным операциям с файлом, и как следствие, к нарушению целостности его данных. Такая ситуация является неприемлемой для многих приложений.