Трябва ли да прекратя раздвоен дъщерен процес с exit()?

Работя върху някои неща, използвайки fork() в C. Това е първият ми контакт с концепцията за разклоняващи процеси.

По принцип имам нещо подобно:

int pid;

pid = fork();
if (pid < 0) {
    fprintf(stderr, "Fork Failed");
    exit(-1);
} else if (pid == 0) {
    fprintf(stderr, "Inside child %d\n", getpid());
    // do some other stuff
    exit(0);
} else {
    fprintf(stderr, "Inside parent %d\n", getpid());
}

Преди не бях поставял exit(0) в кода на дъщерния процес. Получавах привидно тонове дублиращи се процеси. Добавих exit(0) и сега създавам само едно дете. Искам обаче да знам дали това е правилна практика или просто превръзка. Това ли е правилното нещо. Как едно дете трябва да "спре", когато е готово?


person n0pe    schedule 01.02.2014    source източник
comment
Как всичко трябва да спре, когато е готово?   -  person Kerrek SB    schedule 01.02.2014
comment
Разклоненият процес е просто процес като всеки друг. Той ще приключи, когато основната функция излезе, или при изрично извикване на exit(), или при непоправима грешка/изключение.   -  person kuroi neko    schedule 01.02.2014
comment
Не съм сигурен как имате тонове процеси без цикъл.   -  person ooga    schedule 01.02.2014


Отговори (2)


Обикновено детето или има свой собствен код с exit, или извиква една от функциите exec, за да замени изображението на своя процес с друга програма. Така че изходът е наред. Но родителят и детето биха могли да изпълнят поне част от същия код, нещо подобно:

int pid = fork();
if (pid < 0) {
    fprintf(stderr, "Fork Failed");
    exit(-1);
} else if (pid == 0) {
    // child code
} else {
   // parent code
}
// shared code
person ooga    schedule 01.02.2014
comment
Добре, така че това е продължение на моя въпрос. Когато детето завърши своя код и премине към споделения код, тогава излиза ли от тази функция и продължава ли да изпълнява останалата част от програмата? Да кажем, че кодът, който сте написали по-горе, е в makeAFork(), дали детето, след като изпълни споделения код, ще се върне от makeAFork() и ще продължи ли да изпълнява неща? - person n0pe; 01.02.2014
comment
Детето продължава да върви накъдето води кодът. Не забравяйте, че детето е отделно (почти) идентично копие на родителя. Върнатата стойност на fork() е всичко, което наистина ги отличава (те също имат различни pid, разбира се, и има няколко други подробности, които могат да се различават). - person ooga; 01.02.2014

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

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h> //fork() is defined in this header file
#include<sys/wait.h>//wait() is defined in this header file
int main()
{
    int pid,a,b;
    printf("\nPlease enter two numbers\n");
    scanf("%d%d",&a,&b);
    pid=fork();
    if(pid<0)
    {
        printf("\nfork failed\n");
        exit(1);
    }
    if(pid==0)
    {
        //you are in chiled process
        //getting child process id
        printf("\n[child %d]: sum of %d and %d is %d\n",getpid(),a,b,a+b);
    }
    else
    {
        //waiting for child process to finish
        wait(NULL);
        //getting parent id
        printf("\n[parent %d]:difference of %d and %d is %d\n",pa_pid,a,b,a-b);
        exit(0);
    }
}
person Prashant Anuragi    schedule 01.02.2014
comment
Имайте предвид, че fork() е дефинирано в <unistd.h>, а не в <sys/types.h>. Също така имайте предвид, че в съвременните версии на POSIX-съвместими системи (тези, създадени през настоящото хилядолетие, а не през последното хилядолетие — казано грубо), не е необходимо изрично да включвате <sys/types.h>. Не се причинява вреда, но не е необходимо. Другите POSIX заглавки или го включват, или включват други заглавки, които дефинират съответните типове, които <sys/types.h> трябва да дефинира. Това е знак за кодиране от „старата школа“. Може да има причини да го включите, като корпоративни стандарти за кодиране или наследени системи, които да бъдат поддържани, но... - person Jonathan Leffler; 19.07.2015
comment
Вашият дъщерен код на процес използва имплицитно return 0; в края на main(); вашият родителски процес използва изричен exit(0);, за да излезе от main(). Ако беше моят код, щеше да има изрично return 0; в края на main() и нямаше директно exit(0) за родителската нишка. Дъщерният код ще бъде в собствена функция, която вероятно ще завършва с изрично exit(0); Може дори да украся функцията на детето с C11 _Noreturn, за да покажа, че не се връща. - person Jonathan Leffler; 19.07.2015