Почему вывод печатается дважды?

Может быть, большинству из вас это покажется ребячеством, но я не могу понять этот небольшой фрагмент кода.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char** argv) {
    int i, pid;
    pid = fork();
    printf("Forking the pid: %d\n",pid);
    for(i =0; i<5; i++)
        printf("%d  %d\n", i,getpid());
    if(pid)
        wait(NULL);
    return (0);
}

Результат этой программы

Forking the pid: 2223
0  2221
1  2221
2  2221
3  2221
4  2221
Forking the pid: 0
0  2223
1  2223
2  2223
3  2223
4  2223
Press [Enter] to close the terminal ...

В цикле for команда printf используется один раз. Почему «разветвление pid» и после этого pid печатаются дважды. Как это работает? Кто-нибудь может мне это объяснить? Заранее спасибо. Может ли кто-нибудь объяснить мне, почему мы должны использовать ожидание здесь? Из справочных страниц я понял, что ожидание возвращает управление родительскому процессу? Правильно ли я понял? Нужно ли использовать ожидание после разветвления процесса? Операционная система: ubuntu, компилятор: gcc, IDE: netbeans


person narayanpatra    schedule 29.09.2010    source источник
comment
Э... Но именно это и делает fork! Вы разветвили процесс, и все после разветвления выполняется дважды, потому что теперь у вас два процесса! Вы в основном спрашиваете, почему fork разветвляется!   -  person AnT    schedule 29.09.2010
comment
возможный дубликат Что делает этот код C?   -  person Steve Weet    schedule 29.09.2010
comment
Это не дубликат любого другого вопроса, но может быть предоставленная вами ссылка поможет мне лучше понять вилку.   -  person narayanpatra    schedule 29.09.2010
comment
Вопрос отредактирован. Теперь о функции ожидания.   -  person narayanpatra    schedule 29.09.2010


Ответы (5)


Но это именно то, что делает fork. Вы разветвили процесс, и все после fork выполняется дважды, потому что теперь у вас есть два процесса, выполняющих один и тот же код печати. Вы в основном спрашиваете, почему fork разветвляется. fork разветвляется, потому что он должен разветвляться. Вот для чего это нужно.

После fork родительский и дочерний процессы обычно выполняются параллельно, а это означает, что хороший последовательный вывод, который вы видите в вашем примере, не гарантируется. Вы могли бы легко получить чередующиеся выходные данные двух процессов.

wait в вашем случае выполняется только из родительского процесса. Это заставляет его ждать завершения дочернего процесса, и только после этого родительский процесс также продолжает завершаться. Вызов wait в данном конкретном примере не очень критичен, так как после этого программа ничего не делает, она просто завершается. Но, например, если вы хотите получить некоторую обратную связь от дочернего процесса в родительский процесс и выполнить дополнительную работу с этой обратной связью в родительском процессе, вам придется использовать wait, чтобы дождаться завершения дочернего процесса. .

person AnT    schedule 29.09.2010

Вызов fork() создает новый процесс. Затем остальная часть кода выполняется в каждом из двух процессов. (справочная страница)

person nmichaels    schedule 29.09.2010

Вы печатаете в обоих процессах. Поместите свой цикл печати в предложение else if (pid):

pid = fork();
if(pid)
{
    printf("Child pid: %d\n",pid);
    wait(NULL);
}
else
{
    for(i =0; i<5; i++)
        printf("%d  %d\n", i,getpid());
}

Видите ли, fork возвращается дважды, один раз в родительском процессе и один раз в дочернем процессе. Он возвращает 0 в дочернем и pid созданного процесса в родительском.

person Fred Larson    schedule 29.09.2010
comment
Извините, я не могу понять. Можете ли вы уточнить? - person narayanpatra; 29.09.2010

Потому что и родительский, и дочерний процессы выводят свои результаты.

См. здесь: http://en.wikipedia.org/wiki/Fork_(операционная_система)#Example_in_C для хорошего примера.

person Vicky    schedule 29.09.2010

fork создает новый процесс и возвращается как в старый процесс (родительский), так и в новый процесс (дочерний).

Вы можете сказать, в каком из них вы находитесь, посмотрев на возвращаемое значение из fork. В родительском процессе он возвращает PID дочернего процесса. В дочернем процессе он возвращает 0.

person Douglas Leeder    schedule 29.09.2010