Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаба4f.doc
Скачиваний:
33
Добавлен:
03.05.2015
Размер:
137.22 Кб
Скачать

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

“Предком” всех процессов является процесс Администратор процессов (процесс procnto). идентификатор PID которого равен 1. Остальные процессы порождаются в результате вызова соответствующей функции другим процессом, именуемыми родительскими. Таких функций несколько:

  • семейство функций exec() отличаются набором аргументов функций, заменяют образ вызвавшего процесса указанным исполняемым файлом:

  • fork() создает дочерний процесс путем "клонирования" родительского процесса;

  • vfork() (“виртуальный fork()") - используется как "облегченная" альтернатива паре вызовов fork() exec(). В отличие oт стандартной функции fork(), она не выполняет реального копирования данных, а просто блокирует родительский процесс, пока дочерний не вызовет ехес()

  • семейство функций spawn*() - сразу порождает дочерний процесс, загрузив указанный исполняемый файл. Наиболее эффективный способ порождения процессов в QNX Neutrino;

  • system() - порождает shell для выполнения командной строки, указанной в качестве аргумента.

Рассмотрим пример создания процесса функцией fork(). В этом примере видно, что функция fork() возвращает целое число, которое в родительском процессе равно нулю, а в дочернем идентификатору процесса:

#include<stdlib.h> /*подключение стандартной библиотеки */

#include <sys/resource.h> /*подключение файла с идентификаторами ресурсов*/

int main(int arge, char **argv, char **cnv)

{

pid_t pid; /* создаем переменную pid типа pid_t (process id) */

char *Prefix; /* создаем переменную Prefix типа char (символ) */

Prefix = (char *) malloc (sizeof(char)); /* Функция malloc захватывает блок памяти по крайней мере не

меньшей, чем из size байтов. Смысл это операции выделение памяти под переменную Prefix */

pid = fork(); /* функция fork() создает процесс и возвращает его ID */

if (pid==0) sprintf(Prefix, "CHILD:"); /* если мы в родительском процессе то возращаем ID потомка */

else sprintf ( Prefix, "PARENT:"); /* если мы в дочернем процессе то возращаем ID родителя */

printf("%s Process name = %s \n", Prefix, argv[0]);

printf("%s PID = %d \n", Prefix, getpid(0));

printf("%s PPID = %d \n", Prefix, getppid(0));

return EXIT_SUCCESS; /* возвращаем значение успешного завершения программы */

}

#include<stdlib.h> /*подключение стандартной библиотеки */

Теперь рассмотрим пример порождение нового процесса с помощью комбинации вызовов vfork() и exec()

#include <sys/resource.h> /*подключение файла с идентификаторами ресурсов*/

int main(int arge, char **argv, char **cnv)

{

pid_t pid; /* создаем переменную pid типа pid_t (process id) */

pid = vfork();

if (pid==0)

{

execlp("process","process",NULL);

perror("Child");

exit(EXIT_FAILURE);

}

waitpid(0,NULL,0);

printf("Parents's PID = %d \n", getpid(0));

printf("Parents's PPID = %d \n", getppid(0));

return EXIT_SUCCESS;

}

Функция waitpid() может приостановить процесс в ожидании изменения состояния определенного дочернего процесса, заданного значением PID. У функции waitpid() три параметра. Первый параметр – значение PID процесса, завершения которого ждет функция. Если передать в этом параметре значение -1, функция будет ждать изменения состояния любого процесса, аналогично wait(). Если первый параметр равен нулю, waitpid() ждет завершения любого процесса из той же группы, что и текущий. Второй параметр waitpid() аналогичен параметру wait(). Третий параметр позволяет указать дополнительные флаги функции. Например, если установить флаг NOHANG, функция вернет управление немедленно, даже если ни один дочерний процесс не завершился (подробнее об этом будет сказано ниже). Результатом функции waitpid(), также как и в случае wait(), является идентификатор завершившегося процесса.

Функция perror печатает сообщение об ошибке в stderr (стандартный поток вывода ошибок). В этом сообщении аргумент string печатается первым, затем печатается двоеточие, системное сообщение об ошибке для последнего библиотечного вызова, выработавшего ошибку, и новая строка. Номер действительной ошибки хранится в переменной errno, которая объявлена на внешнем уровне.

Самый простой и быстрый способ порождения процесса использование функцию spawn()

#include<stdlib.h> /*подключение стандартной библиотеки */

#include <sys/resource.h> /*подключение файла с идентификаторами ресурсов*/

int main(int arge, char **argv, char **cnv)

{

spawnl(P_WAIT,"process","process",NULL);

printf("Parants's PID= %d \n",getpid(0));

printf("Parants's PPID= %d \n",getppid(0));

return EXIT_SUCCESS;

}

spawnl(modeflag,pathname,arg0,arg1...,argn,NULL).

Функции spawn создают и выполняют новый child-процесс. Для загрузки и выполнения child-процесса должно быть доступно достаточно памяти. Аргумент modeflag определяет действия, выбираемые parent-процессом перед и на протяжении spawn. Следующие значения modeflag объявлены в <process.h>

Значение

Его смысл

P_WAIT

Приостанавливает parent-процесс, пока не завершится child-процесс.

P_NOWAIT

Продолжает выполнение parent-процесса, параллельного с child-процессом

P_OVERLAY

Parent-процесс перекрывается с child- процессом; parent-процесс уничтожается (то же действие, что и при вызовах exec)