Системно повикване на вилица в C.

Fork System Call C



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

Фигура 1: Основен работен процес на вилица ()

Фигура 1: Основен работен процес на вилица ()







В тази статия ще ви покажа как да използвате системното извикване fork () за създаване на дъщерни процеси в C. И така, нека започнем.



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

Синтаксисът на системната функция fork () е следният:



вилица pid_t(невалиден);

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





При успех, fork () връща PID на дъщерния процес, който е по -голям от 0. В дъщерния процес връщаната стойност е 0. Ако fork () се провали, то връща -1.

Проста вилица () Пример:

Пример за прост вилица () е даден по -долу:



#включва
#включва
#включва
#включва
#включва

intглавен(невалиден) {
pid_t pid=вилица();

ако(пид== 0) {
printf ('Child => PPID: %d PID: %dн',getppid(),избухвам());
изход (EXIT_SUCCESS);
}
иначе ако(пид> 0) {
printf („Родител => PID: %dн',избухвам());
printf („Изчакване за завършване на дочерния процес.н');
изчакайте(НУЛА);
printf („Детето завърши.н');
}
иначе {
printf („Не може да се създаде дъщерен процес.н');
}

връщанеEXIT_SUCCESS;
}

Тук използвах fork (), за да създам дъщерен процес от основния/родителския процес. След това отпечатах PID (Process ID) и PPID (Parent Process ID) от дъщерния и родителския процес. На родителския процес чакане (NULL) се използва за изчакване за завършване на дъщерния процес. В дъщерния процес exit () се използва за завършване на дъщерния процес. Както можете да видите, PID на родителския процес е PPID на дъщерния процес. Така че, процесът на детето 24738 принадлежи към родителския процес 24731 .

Можете също да използвате функции, за да направите програмата си по -модулна. Ето, използвах processTask () и parentTask () функции съответно за дочерния и родителския процес. Ето как всъщност се използва fork ().

#включва
#включва
#включва
#включва
#включва

невалиденchildTask() {
printf ('Здравей святн');
}

невалиденparentTask() {
printf ('Основна задача.н');
}

intглавен(невалиден) {
pid_t pid=вилица();

ако(пид== 0) {
childTask();
изход (EXIT_SUCCESS);
}
иначе ако(пид> 0) {
изчакайте(НУЛА);
parentTask();
}
иначе {
printf („Не може да се създаде дъщерен процес.“);
}

връщанеEXIT_SUCCESS;
}

Резултатът от горната програма:

Изпълнение на множество дъщерни процеси с помощта на fork () и Loop:

Можете също да използвате цикъл, за да създадете колкото се може повече дъщерни процеси. В примера по -долу създадох 5 дъщерни процеса, използвайки цикъл for. Отпечатах също PID и PPID от дъщерните процеси.

#включва
#включва
#включва
#включва
#включва

intглавен(невалиден) {
за(inti= 1;i<= 5;i++) {
pid_t pid=вилица();

ако(пид== 0) {
printf („Детски процес => PPID =%d, PID =%dн',getppid(),избухвам());
изход (0);
}
иначе {
printf („Родителски процес => PID =%dн',избухвам());
printf („Изчакване за завършване на дъщерните процеси ...н');
изчакайте(НУЛА);
printf („довършителният процес приключи.н');
}
}

връщанеEXIT_SUCCESS;
}

Както можете да видите, идентификаторът на родителския процес е един и същ във всички дъщерни процеси. Така че всички те принадлежат на един и същ родител. Те също се изпълняват по линеен начин. Един след друг. Контролът на детските процеси е сложна задача. Ако научите повече за системното програмиране на Linux и как работи, ще можете да контролирате потока на тези процеси така или иначе.

Пример от реалния живот:

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

В следния пример генерирах 4-цифрен ПИН код в дъщерния процес и го изпратих на родителския процес, основната програма. След това отпечатах ПИН кода от там.

#включва
#включва
#включва
#включва
#включва

intgetPIN() {
// използваме PPID и PID като начало
srand (избухвам() +getppid());
intтайна= 1000 + ред () % 9000;
връщанетайна;
}

intглавен(невалиден) {
intfd[2];
тръба(fd);
pid_t pid=вилица();

ако(пид> 0) {
близо(0);
близо(fd[1]);
след(fd[0]);

intsecretNumber;
size_treadBytes=Прочети(fd[0], &secretNumber, размер на(secretNumber));

printf („Изчаква се ПИН ...н');
изчакайте(НУЛА);
printf ('Прочетени байтове: %ldн',readBytes);
printf („ПИН: %dн',secretNumber);
}
иначе ако(пид== 0) {
близо(1);
близо(fd[0]);
след(fd[1]);

intтайна=getPIN();
пиши(fd[1], &тайна, размер на(тайна));
изход (EXIT_SUCCESS);
}

връщанеEXIT_SUCCESS;
}

Както можете да видите, всеки път, когато стартирам програмата, получавам различен 4-цифрен ПИН код.

Така че по принцип използвате системния разговор fork () в Linux. Благодаря, че прочетохте тази статия.