Файлы, связанные с процессом
В главе 1 мы говорили, что каждый процесс имеет собственный текущий рабочий каталог и собственный корневой каталог. Это лишь два примера того, какие данные должно поддерживать ядро для представления взаимодействия между процессом и файловой системой. Для этой цели используется структура данных типа fs struct а у каждого дескриптора процесса есть поле fs, которое указывает на структуру fs struct этого процесса.
Вторая таблица, адрес которой содержится в поле files дескриптора процесса, указывает, какие файлы открыты процессом в данный момент. Это структура files struct,
Поле fd указывает на массив указателей на файловые объекты.
Размер этого массива хранится в поле max fds. Как правило, fd указывает на поле fd array структуры f iies struct, которое содержит 32 указателя на файловые объекты. Если процесс откроет более 32 файлов, ядро выделит новый массив (большего размера) под указатели и запишет его адрес в поле fd. Кроме ТОГО, ЯДрО обновит СОДержИМОе ПОЛЯ max fds.
Для каждого файла, указатель на который хранится в массиве fd, индекс массива является дескриптором. Обычно первый элемент (с нулевым индексом) массива связывается со стандартным потоком ввода процесса, второй со стандартным потоком вывода, а третий — со стандартным потоком ошибок Процессы в системе Unix используют дескриптор как основной идентификатор файла. Обратите внимание, что, благодаря системным вызовам dup о, dup2 о и fcnti о, два дескриптора могут ссылаться на один и тот же открытый файл, т. е. два элемента массива могут указывать на один и тот
же файловый объект. Пользователи сталкиваются с этим постоянно, когда применяют конструкции оболочки, такие как 2>&1, для перенаправления сообщений об ошибках в стандартный поток вывода.
Процесс не может использовать более чем nr open файловых дескрипторов (обычно это значение равно 1 048 576). Кроме того, ядро накладывает динамическое ограничение на количество файловых дескрипторов в структуре signai->riim[RLiMiT_NOFiLE] дескриптора процесса. Это значение обычно равняется 1024, но оно может быть увеличено, если процесс обладает привилегиями суперпользователя.
Поле open fds первоначально содержит адрес поля open fds init, которое является битовым массивом и идентифицирует дескрипторы файлов, открытых в данный момент. В поле max fdset хранится количество битов этого массива. Поскольку структура данных fd set имеет длину 1024 бита, обычно нет необходимости в увеличении размера этого битового массива. Однако ядро может динамически увеличить его размер, если в том возникнет необходимости, как в случае с массивом файловых объектов.
Ядро содержит функцию fget , которая вызывается, когда ядро приступает к использованию файлового объекта. Эта функция принимает в качестве параметра fd. Она возвращает адрес в current->fiies->fd[fd] (то есть адрес соответствующего файлового объекта) или null, если дескриптору fd не соответствует никакой файл. В первом случае fgeto увеличивает на единицу счетчик обращений к файлу f count.
Ядро также содержит и функцию fput , вызываемую, когда управляющий тракт ядра прекращает использование файлового объекта. Функция принимает в качестве параметра адрес файлового объекта и уменьшает на единицу счетчик обращений к файлу f count. Более того, если это поле становится равным нулю, функция вызывает метод release из числа файловых операций (если таковой определен), уменьшает значение поля i writecount в объекте "индексный дескриптор” (если файл был открыт для записи), удаляет файловый объект из списка суперблока, возвращает файловый объект slab- аллокатору и уменьшает счетчики обращений связанного объекта элемент каталога” и дескриптора файловой системы Функции fget lighto И fput_lightЯВЛЯЮТСЯ ускоренными” ВерСИЯМИ функций fget и fput . Ядро вызывает их, когда можно быть уверенным в том, что текущий процесс уже владеет файловым объектом, т. е. процесс уже увеличил счетчик ссылок файлового объекта. Например, эти функции используются служебными процедурами в системных вызовах, которые получают в качестве аргумента файловый дескриптор, поскольку счетчик ссылок файлового объекта уже был увеличен предыдущим системным вызовом
open.
Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | Следующая страница