Ю. Вахалия - UNIX изнутри (2003) (1114670), страница 20
Текст из файла (страница 20)
Обработчик увидит, что страница помечена как «копируемая при записи», и создаст новую ее новую копию, которую уже можно изменять. Таким образом, происходит копирование только тех страниц памяти, которые требуется изменять, а не всего адресного пространства целиком. Если потомок вызовет ехес или ехЫ, то защита страниц памяти вновь станет обычной, и флаг «копирования при записи» будет сброшен. В системе ВЗ1) (ЛЧ1Х представлен несколько иной подход к решению проблемы, реализованный в новом системном вызове чароги.
Программист может воспользоваться им вместо 5ой, если планирует вслед за ним вызвать ехес. Функция чароги не производит копирования. Вместо этого процесс-родитель предоставляет свое адресное пространство потомку и блокируется до тех пор, пока тот не вернет его. Затем происходит выполнение потомка в адресном пространстве родительского процесса до того времени, пока не будет произведен вызов ехес или ех11, после чего ядро вернет родителю его адресное пространство и выведет его из состояния сна. Системный вызов чтой выполняется очень быстро, так как не копирует даже карты адресации. Адресное пространство передается потомку простым копированием регистров карты адресации. Однако следует отметить, что вызов ч1ой является достаточно опасным, так как позволяет одному процессу испольэовать и даже изменять адресное пространство другого процесса.
Это свойство ч(ой используют различные программы, такие как сап. 2.8.4. Запуск новой программы Системный вызов ехес заменяет адресное пространство вызывающего процесса на адресное пространство новой программы. Если процесс был создан при помощи чгогк, то вызов ехес возвращает старое адресное пространство родительскому процессу. В ином случае этот вызов высвобождает старое адресное пространство.
Вызов ехес предоставляет процессу новое адресное пространство и загружает в него содержимое новой программы. По окончании работы ехес процесс продолжает выполнение с первой инструкции новой программы. Адресное пространство процесса состоит из нескольких определенных компонентов'. + Текст (гехт). Содержит выполняемый код. + Инициализированные данные (~шт)а!1гед дата).
Содержат объекты данных, которые в программе уже имеют начальные значения и соответствуют секции инициализированных данных в выполняемом файле. ' Такое разделение представляется весьма функциональным в теории, однако ядро ие распознает так много различных компонентов. Например, в системе БЪ'К4 адресное пространство видится просто как набор разделяемых или приватных отображений. 2.8. Новые процессы и программы 89 + Неинициализированные данные (цп1п1йа11хес1 г1аса).
Имеет исторически сложившееся название блока статического хранения (Ыоск зсас)с згогайе, Ьээ)'. Содержит переменные, которые были в программе описаны, но значения им присваивались. Объекты в этой области всегда заполнены нулями при первом обращении к ним. Так как хранение нескольких страниц нулей в выполняемом файле представляется нерациональным, в заголовке программы принято просто описывать общий размер этой области и предоставлять операционной системе самой сгенерировать заполненные нулями страницы. + Разделяемая память (зЬагег) шешогу). Многие системы 1)Ь11Х позволяют процессам совместно использовать одни и те же области памяти.
+ Разделяемые библиотеки (зЬагег) 11Ьгаг(ез). Если система поддерживает библиотеки динамической связи, процесс может обладать несколькими отдельными областями памяти, содержащими библиотечный код, а также библиотечные данные, которые могут использоваться и другими процессами. + Куча (Ьеар). Источник динамически выделяемой памяти. Процесс берет память из кучи при помощи еистемных вызовов Ьгк или эЬгк, либо используя функцию ша11ос() из стандартной библиотеки С. Ядро предоставляет кучу каждому процессу и расширяет ее по мере необходимости. + Стек приложения (цзег зсаск).
Ядро выделяет стек каждому процессу, В большинстве традиционных реализаций системы 1)Ь11Х ядро прозрачно отслеживает возникновение исключительных состояний, связанных с переполнением стека, и расширяет стек до определенного в системе максимума. Применение разделяемой памяти является стандартной возможностью Зузгеш Ъ' 111«11Х, но не поддерживается в системе 4ВЯ) (до версии 4.3). Многие коммерческие реализации 1)1ч1Х, основанные на В31), поддерживают как разделяемую память, так и некоторые формы разделяемых библиотек в качестве дополнительных возможностей системы.
В последующем описании работы ехес мы рассмотрим программу, которая не использует ни одну из этих возможностей. Система ()Ь11Х поддерживает различные форматы выполняемых файлов. Первым поддерживаемым форматом был а.оц1, имеющий 32-байтовый заголовок с последующими секциями текста, данных и таблицы символов. Заголовок программы содержит размеры текста, областей инициализированных и неинициализированных данных, а также точку входа, которая является адресом первой инструкции программы, которая будет выполнена. Заголо- ' Морис Бах в широко известной книге «Архитектура операционной системы 1ЛЧ1Х«пишет, что сокращение Ьм имеет происхождение от ассемблерного псевдооператора для машины 1ВМ 7090 и расшифровывается как Ыос1« зсапео' Ьу зушЬо1 (блок, иачииашщийся с символа).
— 77рим. рео. 90 Глава 2, Ядро и процессы вок также содержит магическое ишло, идентифицирующее файл как действи- тельно выполняемый и дающее дополнительную информацию о его форма- те, такую как: требуется ли ему разбиение на страницы или начинается ли секция данных на краю страницы. Набор поддерживаемых магических чисел определен в каждой реализации П)х!1Х по-своему, Системный вызов ехес выполняет следующие действия: 1. Разбирает путь к исполняемому файлу и осуществляет доступ к нему. 2, Проверяет, имеет ли вызывающий процесс полномочия на выполнение файла. 3. Читает заголовок и проверяет, что он действительно исполняемый'.
4. Если для файла установлены биты ЯЛР или БСП), то эффективные идентификаторы 1)П) и СП) вызывающего процесса изменяет на 1)П) и СП), соответствующие владельцу файла. 5. Копирует аргументы, передаваемые в ехес, а также переменные среды в пространство ядра, после чего текущее пользовательское пространство готово к уничтожению. 6. Выделяет пространство свопинга для областей данных и стека.
7. Высвобождает старое адресное пространство и связанное с ним пространство свопинга. Если же процесс был создан при помощи ч1огК производится возврат старого адресного пространства родительскому процессу. 8. Выделяет карты трансляции адресов для нового текста, данных и стека. 9. Устанавливает новое адресное пространство. Если область текста активна (какой-то другой процесс уже выполняет ту же программу), то она будет совместно использоваться с этим процессом. В других случаях пространство должно инициализироваться из выполняемого файла. Процессы в системе 11)х11Х обычно разбиты на страницы, что означает, что каждая страница считывается в память только по мере необходимости.
10. Копирует аргументы и переменные среды обратно в новый стек приложения. 11. Сбрасывает все обработчики сигналов в действия, определенные по умолчанию, так как функции обработчиков сигналов не существуют в новой программе. Сигналы, которые были проигнорированы или заблокированы перед вызовом ехес, остаются в тех же состояниях. 12. Инициализирует аппаратный контекст. При этом большинство регистров сбрасывается в О, а указатель команд получает значение точки входа программы. ' Вызов ехес также может выполнять сценарии команлното интерпретатора, имеющие первую строку типа №!заец паве. 2.8. Новые процессы и программы 91 2.8.5.
Завершение процесса Функция ядра ех11() предназначена для завершения процесса. Она вызывается изнутри, когда процесс завершается по сигналу. С другой стороны, программа может выполнить системный вызов ех11, который, в свою очередь, вызовет функцию ехй(). Функция ехй() производит следующие действия: 1. Отключает все сигналы. 2. Закрывает все открытые файлы. 3.
Освобождает файл программы и другие ресурсы, например текущий каталог. 4. Делает запись в журнал данной учетной записи. 5. Сохраняет данные об использованных ресурсах и статус выхода в структуре ргос. 6. Изменяет состояние процесса на 520МВ (зомби) и помещает его структуру ргос в список процессов-зомби. 7. Устанавливает процесс 1пй любому существующему потомку завершаемого процесса в качестве родителя. 8.
Освобождает адресное пространство, область ц, карты трансляции адресов и пространство свопинга. 9. Посылает родителю завершаемого процесса сигнал 516СН1.0. Этот сигнал обычно игнорируется и реально необходим только в тех случаях, если по какой-то причине родительскому процессу необходимо знать о завершении работы его потомка. 10.
Будит родительский процесс, если тот был приостановлен. 11. Вызывает звтсп0 для перехода к выполнению следующего процесса в расписании. 12. После завершения работы ехй() процесс находится в состоянии зомби. Вызов ехй не освобождает структуру ргос завершенного процесса, так как его родителю, возможно, будет необходимо получить статус выхода и информацию об использовании ресурсов. За освобождение структуры ргос потомка отвечает его процесс-родитель, как будет описано подробнее позже. По завершении этой процедуры структура ргос возвращается в список свободных структур, и на этом процесс «чистки следов» завершается. 2.8.6.
Ожидание завершения процесса Часто родительскому процессу необходимо обладать информацией о завершении работы своего потомка. Например, когда командный интерпретатор, исполняя команду, порождает интерактивный процесс (переводящий 92 Глава 2. Ядро и процессы ввод и вывод на себя) и, становясь его родителем, должен ждать завершения своего потомка, чтобы после этого вновь быть готовым ко вводу очередной команды. Когда завершается фоновый процесс, командному интерпретатору может потребоваться сообщить об этом пользователю (выводом соответствующего сообщения на терминал).