Почему этот код не выводит два «привет» при использовании многопроцессорности? - PullRequest
0 голосов
/ 23 октября 2019

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

Так почему этот кодниже не выводятся два "привет"?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

static int idata = 111; /* Allocated in data segment */

int main(int argc, char *argv[])
{

    int istack = 222; /* Allocated in stack segment */
    pid_t childPid;
    idata *= 2;
    istack *= 2;
    printf("hello\n");

    switch (childPid = fork()) {
            case -1:
                    printf("fork fail\n");
                    exit(0);
            case 0:
                    idata *= 3;
                    istack *= 3;
                    break;
            default:
                    sleep(3); // Give child a chance to execute
                    break;
    }
    /* Both parent and child come here */

    printf("PID=%ld %s idata=%d istack=%d\n", (long) getpid(),
    (childPid == 0) ? "(child) " : "(parent)", idata, istack);

    exit(0);
}

Результат:

привет

PID = 591 (дочерний) idata = 666 istack = 1332

PID = 590 (родительский) idata = 222 istack = 444

почему этот код не печатает два "привет"?

Ответы [ 3 ]

4 голосов
/ 23 октября 2019

printf("hello\n"); происходит раньше fork().

Когда выход является терминалом, по умолчанию stdout является линейной буферизацией, он выводит 1 hello, потому что stdout сбрасывается на \n*буферы сбрасываются на exit().

0 голосов
/ 23 октября 2019

Трассировка потока программы. Во-первых, есть только один процесс, выполняющий эту программу. Этот процесс печатает "привет". Далее, есть системный вызов fork внутри оператора switch. Теперь есть два процесса, родительский и дочерний. Ребенок является клоном родителя. Все, кроме идентификатора процесса, одинаково для обоих. Даже следующая команда, которая будет выполнена, одинакова для обоих. И родитель, и потомок выполняют оператор switch следующим образом. У ребенка никогда не было возможности напечатать «привет».

0 голосов
/ 23 октября 2019

вы делаете printf("hello\n"); до вызова функции fork().

...