Написание программы с использованием getpid() и getppid()

В качестве примера использования системных вызовов getpid() и getppid() самостоятельно напишите программу, печатающую значения PID и PPID для текущего процесса. Запустите ее несколько раз подряд. Посмотрите, как меняется идентификатор текущего процесса. Объясните наблюдаемые изменения.

Создание процесса в UNIX. Системный вызов fork()

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

· идентификатор процесса – PID ;

· идентификатор родительского процесса – PPID .

Дополнительно может измениться поведение порожденного процесса по отношению к некоторым сигналам, о чем подробнее будет рассказано на семинарах 13–14, когда мы будем говорить о сигналах в операционной системеUNIX.

Системный вызов для порождения нового процесса Прототип системного вызова #include <sys/types.h> #include <unistd.h> pid_t fork(void); Описание системного вызова Системный вызов fork служит для создания нового процесса в операционной системе UNIX. Процесс, который инициировал системный вызов fork , принято называть родительским процессом ( parent process ). Вновь порожденный процесс принято называть процессом-ребенком ( child process ). Процесс-ребенок является почти полной копией родительского процесса. У порожденного процесса по сравнению с родительским изменяются значения следующих параметров: · идентификатор процесса; · идентификатор родительского процесса; · время, оставшееся до получения сигнала SIGALRM ; · сигналы, ожидавшие доставки родительскому процессу, не будут доставляться порожденному процессу. При однократном системном вызове возврат из него может произойти дважды: один раз в родительском процессе, а второй раз в порожденном процессе. Если создание нового процесса произошло успешно, то в порожденном процессе системный вызов вернет значение 0, а в родительском процессе – положительное значение, равное идентификатору процесса-ребенка. Если создать новый процесс не удалось, то системный вызов вернет в инициировавший его процесс отрицательное значение. Системный вызов fork является единственным способом породить новый процесс после инициализации операционной системы UNIX.

В процессе выполнения системного вызова fork() порождается копия родительского процесса и возвращение из системного вызова будет происходить уже как в родительском, так и в порожденном процессах. Этот системный вызов является единственным, который вызывается один раз, а при успешной работе возвращается два раза (один раз в процессе-родителе и один раз в процессе-ребенке)! После выхода из системного вызова оба процесса продолжают выполнение регулярного пользовательского кода, следующего за системным вызовом.

Прогон программы с fork() с одинаковой работой родителя и ребенка

Для иллюстрации сказанного давайте рассмотрим следующую программу:

/* Программа 03-1.с – пример создания нового

процесса с одинаковой работой процессов

ребенка и родителя */

#include <sys/types.h>

#include <unistd.h>

#include <stdio.h>

int main()

{

pid_t pid, ppid;

int a = 0;

(void)fork();

/* При успешном создании нового процесса

с этого места псевдопараллельно

начинают работать два процесса: старый

и новый */

/* Перед выполнением следующего выражения

значение переменной a в обоих процессах

равно 0 */

a = a+1;

/* Узнаем идентификаторы текущего и роди-

тельского процесса (в каждом из

процессов !!!) */

pid = getpid();

ppid = getppid();

/* Печатаем значения PID, PPID и вычислен-

ное значение переменной a (в каждом из

процессов !!!) */

printf("My pid = %d, my ppid = %d,

result = %d\n", (int)pid, (int)ppid, a);

return 0;

}

Листинг 3.1. Программа 03-1.с – пример создания нового процесса с одинаковой работой процессов ребенка и родителя.

Наберите эту программу, откомпилируйте ее и запустите на исполнение (лучше всего это делать не из оболочки mc, так как она не очень корректно сбрасывает буферы ввода-вывода). Проанализируйте полученный результат.

Наши рекомендации