Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lr5.doc
Скачиваний:
1
Добавлен:
08.11.2019
Размер:
70.66 Кб
Скачать

3.2 Системные вызовы exec

Если бы вызов fork был единственным доступным для программиста примитивом создания процессов, то в Linux можно было бы создавать копии только одной программы. Для смены исполняемой программы можно использовать функции семейства ехес.

Рисунок 3.1 Дерево семейства вызовов ехес

Все множество системных вызовов ехес выполняет одну и ту же функцию: они преобразуют вызывающий процесс, загружая новую программу в его пространство памяти. Если вызов ехес завершился успешно, то вызывающая программ полностью замещается новой программой, которая запускается с начала. Результат вызова можно рассматривать как запуск нового процесса, который при этом сохраняет идентификатор вызывающего процесса и по умолчанию наследует файловые дескрипторы (см. пункт 5.5.2).

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

Рассмотрим одну из функций семейства exec.

result =execvp(char *file, char * argv[]);

Функция execvp загружает в текущий процесс программу, которая представлена в системе как файл с именем file и пытается выполнить программу. Вызов execvp передает в программу список строк в виде массива argv с NULL в конце массива. Путь к файлу находится при помощи поиска в каталогах, заданных в переменной среды PATH.

3.3 Доступ к аргументам, передаваемым при вызове exec

Любая программа может получить доступ к аргументам активизировавшего ее вызова exec через параметры, передаваемые ей.

В лабораторной работе №3, часть 2, указывалось, что параметры командной строки могут быть переданы программе в качестве аргументов функции main :

int main(int argc, char *argv[]) {…}

Значение переменной argc равно числу аргументов, переменная argv указывает на массив самих аргументов. Первая строка – argv[0] – это имя программы. Строка argv[i], i=1,…, argc-1 представляет собой i-й аргумент программы.

Поэтому, если программа запускается на выполнение при помощи вызова execvp следующим образом:

char argin[] = (“команда”, “с”, “аргументами”, NULL);

execvp(“prog”, argin);

в программе prog будут истинны следующие выражения:

argc = 3

argv[0] = “команда”

argv[1] = “с”

argv[2] = “аргументами”

argv[3] = NULL

Системные вызовы fork и ехес, объединенные вместе, представляют мощный инструмент для программиста. Благодаря ветвлению при использовании вызова ехес во вновь созданном дочернем процессе программа может выполнять другую программу в дочернем процессе, не стирая себя из памяти.

3.4 Системный вызов wait

Вызов wait временно приостанавливает выполнение процесса, в то время как дочерний процесс продолжает выполняться. После завершения дочернего процесса выполнение родительского процесса продолжится. Если запущено более одного дочернего процесса, то возврат из вызова wait произойдет после выхода из любого из потомков.

Вызов wait часто осуществляется родительским процессом после вызова fork.

Сочетание вызовов fork и wait наиболее полезно, если дочерний процесс предназначен для выполнения совершенно другой программы при помощи вызова ехеc.

#include <sys/types.h>

#include <sys/wait.h>

int result = wait(int * statusptr);

Возвращаемое значение wait обычно является идентификатором дочернего процесса, который завершил свою работу. Если вызов wait возвращает значение -1, это может означать, что дочерние процессы не существуют. Возможность определить завершение каждого из дочерних процессов по отдельности означает, что родительский процесс может выполнять цикл, ожидая завершения каждого из потомков, а после того, как все они завершатся, продолжать свою работу.

Вызов wait принимает один аргумент, status, – указатель на целое число, представляющее собой статусную информацию дочернего процесса. Если указатель равен NULL , то аргумент просто игнорируется. Если же вызову wait передается допустимый указатель, то после возврата из вызова wait переменная status будет содержать полезную информацию о статусе завершения процесса. Обычно эта информация будет представлять собой код завершения дочернего процесса, переданный при помощи вызова exit.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]