Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТОС_2013 / ТОС_6_процессы_слайды.doc
Скачиваний:
7
Добавлен:
03.03.2016
Размер:
899.58 Кб
Скачать

Жизненный путь процесса

Процесс в UNIX создается системным вызовом fork(2).

Процесс, сделав­ший вызов fork(2) называется родительским, а вновь созданный процесс — дочерним.

Новый процесс является точной копией породившего его про­цесса. Новый процесс имеет те же инструкции и данные, что и его родитель.

Выполнение родительского и дочернего процесса начнется с одной и той же инструкции, следующей за вызовом fork(2).

Единственно, чем они различаются — это идентификато­ром процесса PID.

Каждый процесс имеет одного родителя, но может иметь несколько дочерних процессов.

Для запуска задачи, т. е. для загрузки новой программы, процесс должен выполнить системный вызов ехес(2).

При этом новый процесс не порож­дается, а исполняемый код процесса полностью замещается кодом запус­каемой программы.

Тем не менее окружение новой программы во многом сохраняется, в частности сохраняются значения переменных окружения, назначения стандартных потоков ввода/вывода, вывода сообщений об ошибках, а также приоритет процесса.

В UNIX запуск на выполнение новой программы часто связан с порожде­нием нового процесса, таким образом сначала процесс выполняет вызов fork(2), порождая дочерний процесс, который затем выполняет ехес(2), полностью замещаясь новой программой.

рассмотрим эту схему на примере.

Допустим, пользователь, работая в командном режиме (в командном ин­терпретаторе shell) запускает команду ls(l). Текущий процесс (shell) делает вызов fork(2), порождая вторую копию shell. В свою очередь, порожденный shell вызывает ехес(2), указывая в качестве параметра имя исполняемого файла, образ которого необходимо загрузить в память вместо кода shell. Код ls(l) замещает код порожденного shell, и утилита ls(l) начинает вы­полняться. По завершении работы ls(l) созданный процесс "умирает". Пользователь вновь возвращается в командный режим. Описанный про­цесс представлен на рис. 1.5.

Рис. 1.5. Создание процесса и запуск про­граммы

Если сделать “отпечаток” выполняемых процессов, например командой ps(1) , между указанными стадиями, результат был бы следующим:

пользователь работает в командном режиме:

UID PID PPID C STIME TTY TIME CMD

user 745 1 10 10:11:34 ttyp4 0:01 sh

Пользователь запустил команду ls(l), и shell произвел вызов fork(2):

UID PID PPID С STIME TTY TIME CMD

userl 745 1 10 10:11:34 ttyp4 0:01 sh

userl 802 745 14 11:00:00 ttyp4 0:00 sh

Порожденный shell произвел вызов ехес(2):

UID PID PPID С STIME TTY TIME CMD

userl 745 1 10 10:11:34 ttyp4 0:01 sh

userl 802 745 12 11:00:00 ttyp4 0:00 Is

Процесс ls(l) завершил работу:

UID PID PPID С STIME TTY TIME CMD

userl 745 1 10 10:11:34 ttyp4 0:01 sh

Описанная процедура запуска новой программы называется fork-and-exec.

бывают ситуации, когда достаточно одного вызова fork(2) без по­следующего ехес(2).

В этом случае исполняемый код родительского про­цесса должен содержать логическое ветвление для родительского и дочер­него процессов.

Все процессы в UNIX создаются посредством вызова fork(2).

Запуск на выполнение новых задач осуществляется либо по схеме fork-and-exec, либо с помощью ехес(2).

"Прародителем" всех процессов является процесс init(), называемый также распределителем процессов.

Если построить граф "родственных отношений" между процессами, то получится дерево, корнем которого является init(lM).

Показанные на рис. 1.6 процессы schedj и vhand являются системными и формально не входят в иерархию (они! будут рассматриваться в следующих главах).