Форк системного вызова в C

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

fork () используется для создания дочерних процессов в программе на языке C. fork () используется там, где в вашем приложении требуется параллельная обработка. Системная функция fork () определена в заголовках sys/types.h и unistd.h . В программе, в которой вы используете fork, вам также необходимо использовать системный вызов wait (). Системный вызов wait () используется для ожидания в родительском процессе завершения дочернего процесса. Для завершения дочернего процесса в дочернем процессе используется системный вызов exit (). Функция wait () определена в заголовке sys/wait.h , а функция exit () определена в заголовке stdlib.h .

Рис. 1. Базовый рабочий процесс fork ()

В этой статье я покажу вам, как использовать системный вызов fork () для создания дочерних процессов в C. Итак, приступим.

Синтаксис fork () и возвращаемое значение:

Синтаксис системной функции fork () следующий:

pid_t fork (void);

Системная функция fork () не принимает никаких аргументов. Он возвращает целое число типа pid_t .

В случае успеха fork () возвращает PID дочернего процесса, который больше 0. Внутри дочернего процесса , возвращается значение 0. Если fork () завершается неудачно, возвращается -1.

Пример простого fork ():

Пример простого fork (): приведено ниже:

#include
#include
#include
#include
#include

int main (void) {
pid_t pid = fork ();

if (pid == 0) {
printf («Детский => PPID:% d PID:% d n», getppid (), getpid ());
exit (EXIT_SUCCESS);
}
else if (pid> 0) {
printf («Родитель => PID:% d n «, getpid ());
printf (» Ожидание завершения дочернего процесса. n «);
wait (NULL);
printf (» Дочерний процесс завершен. n «);
}
else {
printf (» Невозможно создать дочерний процесс. n «);
}

return EXIT_SUCCESS;
}

Ее е, я использовал fork () для создания дочернего процесса из основного/родительского процесса. Затем я распечатал PID (идентификатор процесса) и PPID (идентификатор родительского процесса) из дочернего и родительского процессов. В родительском процессе wait (NULL) используется для ожидания завершения дочернего процесса. В дочернем процессе exit () используется для завершения дочернего процесса. Как видите, PID родительского процесса — это PPID дочернего процесса. Итак, дочерний процесс 24738 принадлежит родительскому процессу 24731 .

Вы также можете использовать функции, чтобы сделать вашу программу более модульной. Здесь я использовал функции processTask () и parentTask () для дочернего и родительского процессов соответственно. Вот как на самом деле используется fork ().

#include
#include
#include
#include
#include

void childTask () {
printf («Hello World n «);
}

void parentTask () {
printf (» Основная задача. n «);
}

int main (void) {
pid_t pid = fork ();

if (pid == 0) {
childTask () ;
exit (EXIT_SUCCESS);
}
else if (pid> 0) {
wait (NULL);
parentTask ();
}
else {
printf («Невозможно создать дочерний процесс.»);
}

return EXIT_SUCCESS;
}

Вывод вышеуказанной программы:

Запуск нескольких дочерних процессов с использованием fork () и Loop:

Вы также можете использовать цикл для создания столько дочерних процессов, сколько вам нужно. В приведенном ниже примере я создал 5 дочерних процессов, используя цикл for. Я также распечатал PID и PPID из дочерних процессов.

#include
#include
#include
#include
#include

int main (void) {
for (int i = 1; i pid_t pid = fork ();

if (pid == 0) {
printf («Дочерний процесс => PPID =% d, PID =% d n», getppid (), getpid ());
exit (0);
}
else {
printf («Родительский процесс => PID =% d n», getpid ());
printf («Ожидание завершения дочерних процессов … n «);
wait (NULL);
printf (» дочерний процесс завершен. n «);
}
}

return EXIT_SUCCESS;
}

Как видите, ID родительского процесса одинаков для всех дочерних процессов. Итак, все они принадлежат одному родителю. Они также работают линейно. Один за другим. Управление дочерними процессами — сложная задача. Если вы узнаете больше о системном программировании Linux и о том, как оно работает, вы сможете управлять потоком этих процессов любым удобным для вас способом.

Пример из реальной жизни:

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

В следующем примере I ‘ Мы сгенерировали 4-значный PIN-код в дочернем процессе и отправили его родительскому процессу, основной программе. Затем я распечатал оттуда PIN-код.

#include
#include
#include
#include
#include

int getPIN () {
//использовать PPID и PID в качестве начального значения
srand (getpid () + getppid ());
int secret = 1000 + rand ()% 9000;
return secret;
}

int main (void) {
int fd [2];
pipe (fd);
pid_t pid = fork ();

if (pid> 0) {
close ( 0);
close (fd [1]);
dup (fd [0]);

int secretNumber;
size_t readBytes = read (fd [0], & secretNumber, sizeof (secretNumber));

printf («Ожидание PIN-кода … n»);
wait (NULL);
printf («Прочитано байтов:% ld n», readBytes);
printf («PIN:% d n», secretNumber);
}
else if (pid == 0) {
close (1);
close (fd [0]);
dup (fd [1]);

int secret = getPIN ();
write (fd [1], & secret, sizeof (secret));
exit (EXIT_SUCCESS);
}

return EXIT_SUCCESS;
}

Как видите, каждый раз, когда я запускаю программу, я получаю другой 4-значный PIN-код .

Итак, вот как вы в основном используете системный вызов fork () в Linux. Спасибо, что прочитали эту статью.

Оцените статью
nanomode.ru
Добавить комментарий