Программирование на C

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

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

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

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

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

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

pid_t fork (недействительно);

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

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

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

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

#включать
#включать
#включать
#включать
#включать
 
int main (void)
pid_t pid = fork ();
 
if (pid == 0)
printf ("Дочерний => PPID:% d PID:% d \ n", getppid (), getpid ());
выход (EXIT_SUCCESS);

else if (pid> 0)
printf ("Родитель => PID:% d \ n", getpid ());
printf ("Ожидание завершения дочернего процесса.\ n ");
ждать (NULL);
printf ("Дочерний процесс завершен.\ n ");

еще
printf ("Невозможно создать дочерний процесс.\ n ");

 
вернуть EXIT_SUCCESS;

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

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

#включать
#включать
#включать
#включать
#включать
 
void childTask ()
printf ("Привет, мир \ n");

 
void parentTask ()
printf ("Основная задача.\ n ");

 
int main (void)
pid_t pid = fork ();
 
if (pid == 0)
childTask ();
выход (EXIT_SUCCESS);

else if (pid> 0)
ждать (NULL);
parentTask ();

еще
printf ("Невозможно создать дочерний процесс.");

 
вернуть EXIT_SUCCESS;

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

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

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

#включать
#включать
#включать
#включать
#включать
 
int main (void)
для (int i = 1; i <= 5; i++)
pid_t pid = fork ();
 
if (pid == 0)
printf ("Дочерний процесс => PPID =% d, PID =% d \ n", getppid (), getpid ());
выход (0);

еще
printf ("Родительский процесс => PID =% d \ n", getpid ());
printf ("Ожидание завершения дочерних процессов… \ n");
ждать (NULL);
printf ("дочерний процесс завершен.\ n ");


 
вернуть EXIT_SUCCESS;

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

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

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

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

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

 
int main (void)
int fd [2];
труба (фд);
pid_t pid = fork ();
 
if (pid> 0)
закрыть (0);
закрыть (fd [1]);
dup (fd [0]);
 
int secretNumber;
size_t readBytes = читать (fd [0], & secretNumber, sizeof (secretNumber));
 
printf ("Ожидание PIN… \ n");
ждать (NULL);
printf ("Прочитано байтов:% ld \ n", readBytes);
printf ("ПИН:% d \ n", secretNumber);

else if (pid == 0)
закрыть (1);
закрыть (fd [0]);
dup (fd [1]);
 
int secret = getPIN ();
write (fd [1], & secret, sizeof (секрет));
выход (EXIT_SUCCESS);

 
вернуть EXIT_SUCCESS;

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

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

Лучшие эмуляторы игровой консоли для Linux
В этой статье будет перечислено популярное программное обеспечение для эмуляции игровых консолей, доступное для Linux. Эмуляция - это уровень совмести...
Лучшие дистрибутивы Linux для игр в 2021 году
Операционная система Linux прошла долгий путь от своего первоначального простого серверного вида. Эта ОС значительно улучшилась за последние годы и те...
Как записать и транслировать игровую сессию в Linux
В прошлом игры считались только хобби, но со временем игровая индустрия увидела огромный рост с точки зрения технологий и количества игроков. Игровая ...