|
|||||||
|
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Процессы. Системные вызовы fork() и exec()Лабораторная работа 2 Процесс в Linux (как и в UNIX) - это программа, которая выполняется в отдельном защищенном виртуальном адресном пространстве. Когда пользователь регистрируется в системе, автоматически создается новый процесс, в котором выполняется оболочка (shell), например, /bin/bash. Если интерпретатору (shell) встречается команда, соответствующая выполняемому файлу, интерпретатор выполняет ее, начиная с точки входа (entry point). Для С-программ entry point - это функция main. Запущенная программа тоже может создать процесс, т.е. запустить какую-то программу и ее выполнение тоже начнется с функции main. Часть времени процесс выпоняется в режиме задачи (пользовательском режиме) и тогда он выпоняет собственный код, часть времени процесс выпоняется в режиме ядра и тогда он выполняет реентерабельный код операционной системы. В Linux поддерживается классическая схема мультипрограммирования. Linux поддерживает параллельное (или квазипараллельное при наличии только одного процессора) выполнение процессов пользователя. Каждый процесс выполняется в собственном защищенном виртуальном адресном пространстве, т.е. процессы защищены друг от друга и крах одного процесса никак не повлияет на другие выполняющиеся процессы и на всю систему в целом. Ядро предоставляет системные вызовы для создания новых процессов и для управления запущенными процессами. Любая программа может начать выполняться только если другой процесс ее запустит. Для создания процессов используется системный вызов fork(). В Unix и Unix-подобных ОС процесс создается только системным вызовом fork(). Системный вызов fork() создает новый процесс, который является копией процесса-предка: процесс-потомок наследует адресное пространство процесса-предка, дескрипторы всех открытых файлов и сигнальную маску. Другими словами, программа которую выполняет процесс-потомок является программой родительского процесса. Процесс потомок имеет идентичные с родителем области данных и стека. Процесс-потомок начинает работу в режиме задачи после возвращения из системного вызова fork(). Тот факт, что образы памяти, переменные, регистры и все остальное и у родительского процесса, и у дочернего идентичны, могло бы привести к невозможности различить эти процессы, однако, системный вызов fork() возвращает дочернему процессу число 0, а родительскому — отличный от нуля PID (Process IDentifier — идентификатор процесса) дочернего процесса. Оба процесса обычно проверяют возвращаемое значение и действуют соответственно: #include <unistd.h> int main(void) { { { /* здесь располагается дочерний код */ { return 0; } Если вызов fork() завершается аварийно, он возвращает -1. Обычно это происходит из-за ограничения числа дочерних процессов, которые может иметь родительский процесс (CHILD_MAX), в этом случае переменной errno будет присвоено значение EAGAIN. Если для элемента таблицы процессов недостаточно места или не хватает виртуальной памяти, переменная errno получит значение ENOMEM. В старых Unix-системах код предка копировался в адресное пространство процесса-потомка. В современных системах применяется, так называемая, оптимизация fork(): для процесса потомка создаются собственные карты трансляции адресов (таблицы страниц), но они ссылаются на адресное пространство процесса-предка (на страницы предка). При этом для страниц адресного пространства предка права доступа меняются на only- read и устанавливается флаг – copy-on-write. Если или предок или потомок попытаются изменить страницу, возникнет исключение по правам доступа. Выполняя это исключение супервизор обнаружит флаг copy-on-write и создаст копию страницы в адресном пространстве того процесса, который пытался ее изменить. Таким образом код процесса-предка не копируется полностью, а создаются только копии страниц, которые редактируются.
Рассмотрим более подробно, что же делается при выполнении вызова fork() (рис.1): 1. Резервируется пространство свопинга для данных и стека процесса-потомка; 2. Назначается идентификатор процесса PID и структура proc потомка; 3. Инициализируется структура proc потомка. Некоторые поля этой структуры копируются от процесса-родителя: идентификаторы пользователя и группы, маски сигналов и группа процессов. Часть полей инициализируется 0. Часть полей инициализируется специфическими для потомка значениями: PID потомка и его родителя, указатель на структуру proc родителя; 4. Создаются карты трансляции адресов для процесса-потомка; 5. Выделяется область u потомка и в нее копируется область u процесса-предка; 6. Изменяются ссылки области u на новые карты адресации и пространство свопинга; 7. Потомок добавляется в набор процессов, которые разделяют область кода программы, выполняемой процессом-родителем; 8. Постранично дублируются области данных и стека родителя и модифицируются карты адресации потомка; 9. Потомок получает ссылки на разделяемые ресурсы, которые он наследует: открытые файлы (потомок наследует дескрипторы) и текущий рабочий каталог; 10. Инициализируется аппаратный контекст потомка путем копирования регистров родителя; 11. Поместить процесс-потомок в очередь готовых процессов; 12. Возвращается PID в точку возврата из системного вызова в родительском процессе и 0 - в процессе-потомке.
Рис. 1 Процессы описываются структурой proc
Эта структура содержит всю информацию о процессе. Информация нахoдится по адресу /usr/src/sys/sys/proc.h:
Поиск по сайту: |
||||||
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (1.229 сек.) |