Статья: Теория вычислительных процессов и структур

main ()

{

pid_t pid; /*process-id в родительском процессе */

printf (“Пока всего один процесс\n”);

printf (“Вызов fork … \n”);

pid = fork (); /*Создание нового процесса */

if (pid = = 0)

printf (“Дочерний процесс\n”);

else if (pid > 0)

printf (“Родительский процесс, pid потомка %d\n, pid”);

else

printf (“Ошибка вызова fork, потомок не создан\n”);

}

Оператор if, следующий за вызовом fork, имеет три ветви. Первая определяет дочерний процесс, соответствующий нулевому значению переменной pid. Вторая задаёт действия для родительского процесса, соответствуя положительному значению переменной pid. Третья ветвь неявно соответствует отрицательному (а на самом деле равно –1) значению переменной pid, которое возвращается, если вызову fork не удаётся создать дочерний процесс. Это может означать, что вызывающий процесс попытался нарушить ограничения (например – число процессов одновременно выполняющихся и запущенных одним пользователем). В обоих случаях переменная errno содержит код ошибки EAGAIN. Обратите также внимание на то, что поскольку оба процесса, созданных программой, будут выполняться одновременно без синхронизации, то нет гарантии, что вывод родительского и дочернего процессов не будет смешиваться.

Для смены исполняемой программы можно использовать функции семейства exec. Основное отличие между разными функциями в семействе состоит в способе передачи параметров. Как видно из рис. 2.2, все эти функции выполняют один системный вызов execve.

Рис. 2.2. Дерево семейства вызовов exec

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

#include <unistd.h>

/* Для семейства вызовов execl аргументы должны быть списком, заканчивающимся NULL*/

/* Вызову execl нужно передать полный путь к файлу программы */

int execl (const char *path, const char *arg0,..., const char argn, (char *)0);

/* Вызову execlp нужно только имя файла */

int execlp (const char *file, const char *arg0,..., const char argn, (char *)0);

/* Для семейства вызовов execv нужно передать массив аргументов */

int execv (const char *path, char *const argv[]);

int execvp (const char *file, char *const argv[]);

Следующая программа использует вызов execl для запуска программы вывода содержимого каталога ls:

#include <unistd.h>

К-во Просмотров: 574
Бесплатно скачать Статья: Теория вычислительных процессов и структур