Системни разговори

Fork System Call Linux

Fork System Call Linux

Fork System Call

Системното повикване на вилицата се използва за създаване на нови процеси. Новосъздаденият процес е дъщерният процес. Процесът, който извиква fork и създава нов процес, е родителският процес. Процесът дете и родител се изпълняват едновременно.

Но процесите дете и родител се намират в различни пространства на паметта. Тези пространства на паметта имат едно и също съдържание и каквато и операция да се изпълнява от единия процес, няма да засегне другия процес.

Когато се създава процеса на дете; сега и двата процеса ще имат един и същ брояч на програми (PC), така че и двата процеса ще сочат към една и съща следваща инструкция. Файловете, отворени от родителския процес, ще бъдат еднакви за дъщерния процес.

Детският процес е точно същият като неговия родител, но има разлика в идентификаторите на процесите:

  1. Идентификаторът на процеса на дъщерния процес е уникален идентификатор на процеса, който се различава от идентификационните номера на всички други съществуващи процеси.
  2. Идентификаторът на процеса на родител ще бъде същият като този на идентификатора на процеса на родителя на детето.

Свойства на дъщерния процес

По-долу са дадени някои от свойствата, които има дъщерният процес:

  1. Броячите на процесора и използването на ресурсите се инициализират за нулиране.
  2. Когато родителският процес е прекратен, дъщерните процеси не получават никакъв сигнал, тъй като атрибутът PR_SET_PDEATHSIG в prctl () е нулиран.
  3. Нишката, използвана за извикване на fork (), създава дъщерния процес. Така че адресът на дъщерния процес ще бъде същият като този на родителя.
  4. Файловият дескриптор на родителския процес се наследява от дъщерния процес. Например изместването на файла или състоянието на флаговете и I / O атрибутите ще бъдат споделени между файловите дескриптори на дъщерни и родителски процеси. Така че файловият дескриптор на родителския клас ще се позовава на същия файлов дескриптор на детския клас.
  5. Дескрипторите на отворени опашки за съобщения на родителския процес се наследяват от дъщерния процес. Например, ако дескриптор на файл съдържа съобщение в родителски процес, същото съобщение ще присъства в съответния дескриптор на файл на дъщерния процес. Така че можем да кажем, че стойностите на флага на тези файлови дескриптори са еднакви.
  6. По същия начин отворените потоци от директории ще бъдат наследени от дъщерните процеси.
  7. Стойността по подразбиране на таймера на дъщерния клас е същата като текущата стойност на отпуска на таймера на родителския клас.

Свойства, които не се наследяват от Child процес

По-долу са някои от свойствата, които не са наследени от дъщерен процес:

  1. Заключване на паметта
  2. Чакащият сигнал на дъщерния клас е празен.
  3. Обработвайте свързани заключвания на записи (fcntl ())
  4. Асинхронни I / O операции и I / O съдържание.
  5. Известия за промяна на директорията.
  6. Таймери като alarm (), setitimer () не се наследяват от дъщерния клас.

вилица () в C

Няма аргументи във fork (), а върнатият тип fork () е цяло число. Трябва да включите следните заглавни файлове, когато се използва fork ():

#include
#include
#include

Когато работите с вилица (), може да се използва за тип pid_t за идентификатори на процеси, както е дефиниран pid_t .

Заглавният файл където е дефиниран fork (), така че трябва да го включите в програмата си, за да използвате fork ().

Типът на връщане е дефиниран в и повикването fork () е дефинирано в . Следователно трябва да включите и двете във вашата програма, за да използвате системно повикване fork ().

Синтаксис на fork ()

Синтаксисът на системното извикване на fork () в Linux, Ubuntu е както следва:

pid_t fork (void);

В синтаксиса типът на връщане е pid_t. Когато дъщерният процес е създаден успешно, PID на дъщерния процес се връща в родителския процес и 0 ще бъде върнат на самия дъщерен процес.

Ако има някаква грешка, -1 се връща в родителския процес и дъщерният процес не се създава.

Не се предават аргументи на fork (). 

Пример 1: Извикване на вилица ()

Да разгледаме следния пример, в който сме използвали системното повикване fork (), за да създадем нов дъщерен процес:

КОД:

#include
#include
#include
int main ()

вилица ();
printf ("Използване на системно повикване fork () \ n");
връщане 0;

ИЗХОД:

Използване на системно повикване fork ()
Използване на системно повикване fork ()

В тази програма използвахме fork (), това ще създаде нов дъщерен процес. Когато се създаде дъщерният процес, и родителският процес, и дъщерният процес ще сочат към следващата инструкция (същия брояч на програмите). По този начин останалите инструкции или C изрази ще бъдат изпълнени общият брой пъти на процеса, т.е. 2н пъти, където n е броят на системните повиквания на fork ().

Така че, когато повикването fork () се използва еднократно, както по-горе (21 = 2) ще имаме изход 2 пъти.

Тук, когато се използва системното повикване fork (), вътрешната структура ще изглежда така:

Да разгледаме следния случай, в който вилицата () се използва 4 пъти:

КОД:

#include
#include
#include
int main ()

вилица ();
вилица ();
вилица ();
вилица ();
printf ("Използване на системно повикване fork ()");
връщане 0;

Изход:

Използване на системно обаждане fork () Използване на системно повикване fork () Използване на системно повикване fork () Използване на системно повикване fork () Използване на системно повикване fork () Използване на системно повикване fork () Използване на системно повикване fork () Използване на системно повикване fork () Използване на fork () системно обаждане Използване на fork () системно повикване Използване на fork () системно повикване Използване на fork () системно повикване Използване на fork () системно повикване Използване на fork () системно повикване Използване на fork () системно повикване Използване на fork () системно повикване 

Сега общият брой на създадения процес е 24 = 16 и ние имаме нашата инструкция за печат, изпълнена 16 пъти.

Пример 2: Тестване дали fork () е бил успешен

В следващия пример използвахме конструкцията за вземане на решения, за да тестваме стойността (int), върната от fork (). И се показват съответните съобщения:

КОД:

#include
#include
#include
int main ()

pid_t p;
p = вилица ();
ако (p == - 1)

printf ("Има грешка при извикване на fork ()");

ако (p == 0)

printf ("Ние сме в процес на деца");

друго

printf ("Ние сме в родителския процес");

връщане 0;

ИЗХОД:

Ние сме в родителския процес
Ние сме в детския процес

В горния пример използвахме типа pid_t, който ще съхранява връщаната стойност на fork (). fork () се извиква на линия:

p = вилица ();

Така че целочислената стойност, върната от fork (), се съхранява в p и след това p се сравнява, за да се провери дали нашето повикване fork () е било успешно.

Когато се използва повикването fork () и детето бъде създадено успешно, идентификаторът на дъщерния процес ще бъде върнат в родителския процес и 0 ще бъде върнат в дъщерния процес.Идентификационният номер на дъщерния процес в родителския процес няма да бъде същият като идентификационен номер на дъщерния процес в самия детски процес. В детски процес идентификаторът на дъщерния процес ще бъде 0.

С този урок можете да видите как да започнете със системното извикване на fork в linux.

Най-добрите игри за игра с ръчно проследяване
Oculus Quest наскоро представи страхотната идея за ръчно проследяване без контролери. С непрекъснато нарастващия брой игри и дейности, които изпълнява...
Как да покажете OSD наслагване в приложения на цял екран за Linux и игри
Играта на цял екран или използване на приложения в режим на цял екран без разсейване може да ви откъсне от съответната системна информация, видима в п...
Топ 5 карти за залавяне на игри
Всички сме виждали и обичаме поточни игри в YouTube. PewDiePie, Jakesepticye и Markiplier са само някои от най-добрите геймъри, които са спечелили мил...