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

9 Создание порожденного процесса

Для создания порожденного процесса используется функция fork:

pid_t fork (void).

Тип pid_t определен в <sys/types.h> и соответствует типу int. При успешном выполнении создается порожденный процесс и функция возвращает идентификатор этого порожденного процесса родительскому процессу. Порожденный процесс получает от fork нулевой код возврата.

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

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

Функция exit завершает процесс. Ее прототип имеет вид:

void exit (int exit_code),

где exit_code – код завершения процесса.

Простейший пример создания нового процесса:

#include <iostream.h>

#include <sys/wait.h>

#include <unistd.h>

int main()

{ int status;

if (fork())

{ cout << "Child process\n";

exit(0);

};

cout << "Parent process\n";

}

Родительский процесс использует функции wait и waitpid для перехода в режим ожидания завершения порожденного процесса и для выборки его статуса завершения. Прототипы этих функций выглядят так:

pid_t wait (int status_p);

pid_t waitpid (pid_t child_pid, int* status_p,

int options).

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

Функция waitpid является более универсальной, в ней с помощью аргумента child_pid можно указать, завершения какого из порожденных процессов следует ожидать.

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

int execl (const char* path, const char* arg, ).

Первый аргумент функции является либо полным путевым именем, либо именем файла программы, подлежащей исполнению. Аргументы arg являются аргументами для программы, вызванной функцией exec. Они отображаются в переменную argv функции main новой программы. При этом arg отображается в argv[0], значение, указанное после arg, - в argv[1] и т. д. Список аргументов заканчивается нулевым значением.

Пример.

#include <stdio.h>

#include <unistd.h>

int main()

{

char s1[8]="string1", s2[4]="string2";

execl ("./b.out", s1, s2, 0);

return 0;

}

Здесь вызывается программа b.out, скомпилированная из файла

#include <stdio.h>

int main(int argc, char* argv[])

{

printf("%s\n",argv[0]);

printf("%s\n",argv[1]);

return 0;

}

В результате выполнения примера будут выведены строки string1

string2

Большинство программ вызывают exec в порожденном процессе, так как выполнение родительского процесса после вызова exec желательно продолжить. Однако программа может вызвать exec без fork, аfork без exec.