Читаем Архитектура операционной системы UNIX полностью

Напомним, что если область при выполнении алгоритма allocreg (Раздел 6.5.2) выделяется впервые, ядро увеличивает значение счетчика ссылок на индекс, ассоциированный с областью, при этом значение счетчика ссылок нами уже было увеличено в самом начале выполнения функции exec (алгоритм namei). Поскольку ядро уменьшает значение счетчика только один раз в завершение выполнения функции exec (по алгоритму iput), значение счетчика ссылок на индекс файла, ассоциированного с разделяемой областью команд и исполняемого в настоящий момент, равно по меньшей мере 1. Поэтому когда процесс разрывает связь с файлом (функция unlink), содержимое файла остается нетронутым (не претерпевает изменений). После загрузки в память сам файл ядру становится ненужен, ядро интересует только указатель на копию индекса файла в памяти, содержащийся в таблице областей; этот указатель и будет идентифицировать файл, связанный с областью. Если бы значение счетчика ссылок стало равным 0, ядро могло бы передать копию индекса в памяти другому файлу, тем самым делая сомнительным значение указателя на индекс в записи таблицы областей: если бы пользователю пришлось исполнить новый файл, используя функцию exec, ядро по ошибке связало бы его с областью команд старого файла. Эта проблема устраняется благодаря тому, что ядро при выполнении алгоритма allocreg увеличивает значение счетчика ссылок на индекс, предупреждая тем самым переназначение индекса в памяти другому файлу. Когда процесс во время выполнения функций exit или exec отсоединяет область команд, ядро уменьшает значение счетчика ссылок на индекс (по алгоритму freereg), если только связь индекса с областью не помечена как «неотъемлемая».

алгоритм xalloc /* выделение и инициализация области команд */

входная информация: индекс исполняемого файла

выходная информация: отсутствует

{

 if (исполняемый файл не имеет отдельной области команд) return;

 if (уже имеется область команд, ассоциированная с индексом исполняемого файла) {

  /* область команд уже существует… подключиться к ней */

  заблокировать область;

  do while (содержимое области еще не доступно) {

   /* операции над счетчиком ссылок, предохраняющие от глобального удаления области */

   увеличить значение счетчика ссылок на область;

   снять с области блокировку;

   sleep (пока содержимое области не станет доступным);

   заблокировать область;

   уменьшить значение счетчика ссылок на область;

  }

  присоединить область к процессу (алгоритм attachreg);

  снять с области блокировку;

  return;

 }

 /* интересующая нас область команд не существует — создать новую */

 выделить область команд (алгоритм allocreg); /* область заблокирована */

 if (область помечена как «неотъемлемая»)

  отключить соответствующий флаг;

 подключить область к виртуальному адресу, указанному в заголовке файла (алгоритм attachreg);

 if (файл имеет специальный формат для системы с замещением страниц) /* этот случай будет рассмотрен в главе 9 */

 else /* файл не имеет специального формата */

  считать команды из файла в область (алгоритм loadreg);

 изменить режим защиты области в записи частной таблицы областей процесса на «read-only»;

 снять с области блокировку;

}

Рисунок 7.23. Алгоритм выделения областей команд

Рисунок 7.24. Взаимосвязь между таблицей индексов и таблицей областей в случае совместного использования процессами одной области команд

Перейти на страницу:

Все книги серии Серия книг по программному обеспечению издательства prentice hall

Похожие книги