вфорк никогда не вернется - PullRequest
3 голосов
/ 13 июля 2011

Почему эта программа никогда не вернется и продолжит создавать дочерние процессы?

int main()
{
    pid_t pid;
    int foo1 = 1, foo2 = 2;
    printf("before fork()\n");

    if ((pid = vfork()) < 0 ) {
            printf("fork failed.\n");
    }else if (pid == 0) {
            foo1++;
            foo2++;
            printf("child process: pid is %d, my parent pid is  %d\n", getpid(), getppid());
    }else if (pid > 0){
            printf("parent process: pid is %d\n", getpid());
    }

    printf("%s: foo1 is %d, foo2 is %d\n",pid == 0 ? "child process" : "parent process", foo1, foo2);
    return 0;
}

вывод будет выглядеть так:

before fork()
child process: pid is 17244, my parent pid is  15839
child process: foo1 is 2, foo2 is 3
parent process: pid is 15839
parent process: foo1 is -1079005816, foo2 is -1218256081
before fork()
child process: pid is 17245, my parent pid is  15839
child process: foo1 is 2, foo2 is 3
parent process: pid is 15839
parent process: foo1 is -1079005816, foo2 is -1218256081
before fork()
.....
.....

Если добавить _exit во второй блок if, то он 'Хорошо.Я знаю, что vfork делят то же адресное пространство с родительским процессом, но более разумно, если программа завершается сбоем, а не бесконечным циклом.

Ответы [ 3 ]

4 голосов
/ 13 июля 2011

vfork - очень сложный системный вызов, и его единственное предназначение - немедленно иметь execve в дочернем элементе - для других видов использования это опасно и непредсказуемо.

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

1 голос
/ 13 июля 2011

из руководства:

поведение не определено, если процесс, созданный vfork (), либо изменяет любые данные, кроме переменной типа pid_t, используемой для хранения возвращаемого значения из vfork (), или возвращает изфункция, в которой была вызвана vfork (), или вызывает любую другую функцию перед успешным вызовом _exit () или одной из функций семейства exec.

Поскольку родительский и дочерний элементы совместно используют адресное пространство, вы не должны возвращаться изфункция, которая вызвала vfork (); это может привести к повреждению стека родителя .

0 голосов
/ 21 февраля 2012

Внутри дочернего элемента vfork вы можете вызывать только функции, безопасные для вызова в обработчиках сигналов, поэтому printf изнутри vfork - очень плохая идея.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...