Здесь мы собираемся обсудить разветвление, обработанное на языке C.

Мы видели множество процессов в нашем мониторе ресурсов (Linux), top (Linux), диспетчере задач (Windows) или в диспетчере действий (MAC OS). И мы также знаем, что это обработка, выполняемая на компьютере. Но задумывались ли вы когда-нибудь о том, как они создаются? Конечно, они создаются нашей ОС и другими утилитами, чтобы предоставить нам различные функции, такие как графический интерфейс, сеть и т. Д. Но может быть какой-то способ создать эти процессы.

Мы знаем, что эти процессы являются экземплярами или запущенными версиями / экземплярами наших программ, скомпилированных из исходного кода.

Пример,

Итак, как видите, мы собрали исходный код простой программы Hello World. И называет свой выходной или исполняемый файл helloworld. Когда мы выполняем этот исполняемый файл helloworld, мы будем именем процесса.

Когда мы запускаем этот исполняемый файл, мы можем видеть этот процесс в нашем системном мониторе или диспетчере задач.

Ага! Если вы не знаете, так создаются и выглядят процессы в ОС. И мы просто создали процесс.

Если вы запустите этот «helloworld» несколько раз, вы увидите несколько экземпляров в «диспетчере задач». т.е. Одна программа может производить несколько процессов. Нам просто нужно запускать ее несколько раз.

Итак, когда наш компьютер запускается, должен быть первый процесс. Этот процесс запускает все остальные процессы, которые ему нужны.

Когда мы видим списки обработанных в нашем диспетчере задач, они создаются каким-то процессом. Так что на самом деле это и иерархия родительских и дочерних процессов.

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

Наша ОС отслеживает все процессы, присваивая уникальный идентификатор всем процессам, вызывающим «идентификатор процесса» или «pid». Вы можете увидеть PID на изображении выше.

На изображении ниже первый процесс - «init». Он создал процессы «login», «apache» и «ssh». Потом у этих детей тоже есть дети.

Но мы видели только работающий код c как процесс. Как создать новый процесс в программировании на c.

(Мы собираемся увидеть подход к созданию процесса на основе Linux и UNIX. Поэтому, если вы работаете на компьютере с Windows, я предлагаю вам использовать Cygwin или запускать Linux в VirtualBox.)

В Linux функция fork () используется в C для создания нового процесса.

fork ()

Наша цель - выполнение программы C, или, когда программа c работает, может возникнуть ситуация, когда мы хотим создать процесс, например

  • мы хотим запустить другое приложение
  • мы хотим, чтобы какая-то конкретная часть нашего кода работала в / как другой процесс.

Итак, когда мы используем функцию fork, она создает новый запущенный процесс, содержащий тот же код, что и процесс, и начинает выполнение вместе с родительским процессом. Обратите внимание, что он запускается из кода, начинающегося после fork() вызова функции. Поэтому родители и дети используют один и тот же код, но их идентификаторы PID разные. Нет адресного пространства, в этих двух процессах используются общие переменные.

Но почему мы хотим, чтобы два процесса выполняли один и тот же код. Сначала поймите, что fork() используется просто для создания дочернего процесса. Нам нужно выполнить дальнейшую логику для кода, который мы хотим запустить в дочернем процессе. А это очень просто.

Теперь давайте напишем код ...

Чтобы использовать fork(), нам нужно включить следующий файл заголовка.

#include <unistd.h>

Привет, мир в fork ()

#include <stdio.h>
#include <unistd.h>
int main() {
   fork();
   printf("Hello world!\n");
   return 0;
}

вывод:

Hello world!
Hello world!

Объяснение:

Мы знаем, что после вызова fork() создается новый дочерний процесс, и как родительский, так и дочерний процесс начинают выполняться со следующего, например. Таким образом, на выходе один из выходных данных - от дочернего, а другой - от родительского.

Привет, мир fork() , но с некоторыми улучшениями

fork() не принимает никаких аргументов. Но возвращает int. А теперь подумайте, что было бы нужно и чего мы хотим от fork().

помните, что бы fork() не возвращал, это будет перехвачено как родительским, так и дочерним процессом.

Итак, если бы мы были родителями, мы хотели бы присматривать за своими детьми. и если бы мы были ребенком, нам не важна информация наших родителей, мы просто хотим знать, что мы ребенок.

Итак, возвращаемые значения должны быть такими, как родительский PID получает дочерний процесс, а дочерний процесс должен знать, что это дочерний процесс. И это именно так. Возвращаемое значение для родительского процесса содержит PID дочернего процесса, а возвращаемое значение дочернего процесса содержит «0». Но иногда функция fork () не может быть создана (из-за некоторых ошибок времени выполнения), тогда она возвращает отрицательное значение.

Отрицательное значение: создание дочернего процесса не удалось.
Ноль: возвращено во вновь созданный дочерний процесс.
Положительное значение : Возвращается к родительскому объекту или вызывающему абоненту. Значение содержит идентификатор вновь созданного дочернего процесса.

Поэтому после вызова fork() мы могли использовать эти значения для разделения кода для дочернего и родительского.

#include <stdio.h>
#include <unistd.h>
int main() {
 int pid;
 pid = fork(); 
 if(pid == 0) {
  printf("Hello from child(PID = %d)\n", getpid());
 }else {
  printf("Hello from parent(PID = %d)\n", getpid());
 }
  return 0;
}

Вывод:

Hello from parent(PID = 9288)
Hello from child(PID = 9289)

В приведенной выше программе мы добавили целочисленную переменную pid. Когда fork() возвращаемое значение сохранит его в «pid». Родительский pid содержит идентификатор вновь созданного процесса, а дочерний pid содержит 0;

getpid() - это просто функция для получения идентификатора текущего процесса.

Итак, из оператора «if» оба процесса начинают выполняться. Первый «printf» должен выполняться только в дочернем процессе, так как переменная «pid» в дочернем процессе имеет 0. А второй «printf» должен выполняться только в родительском элементе.

Как видите, родительские и дочерние PID разные. Таким образом, мы можем выполнять разный код в дочернем и родительском процессах.

Существует более сложный способ выполнения кода в дочернем процессе с использованием exec(), см. Статью о нем exec () в C ».