Вопросы по fork()

Я пытаюсь понять fork(), поэтому я собрал следующий пример:

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

void main()
{
   if(fork()==0)
   {
      printf("2");

      if(fork()==0)
      {
          printf("4");
      }
      else
      {
          printf("3");
      }
   } 
   else
   {
      printf("1");
   }
}

Когда я просматривал это на бумаге, я нарисовал следующий эскиз:

enter image description here

Итак, я считаю, что результат должен быть 1234. Однако, когда я запускаю этот код, вывод 12324. Почему это? Где моя ошибка?

Обновление:

После прочтения комментариев было предложено выполнить любое из следующих

  • Добавьте \n в каждый оператор printf
  • ИЛИ: Добавить fflush(stdout); после каждого оператора printf
  • ИЛИ: Добавить setbuf(stdout, NULL); < ---- это то, что я закончил:)

После обновления моего кода вывод был действительно 1234.

Ответ 1

printf() вывод обычно буферизируется по строке. Поэтому, когда вы fork(), новые процессы также получают копию буфера. Когда процесс завершается, весь буфер очищается (или в любое время, когда он очищается в коде или всякий раз, когда буфер заполняется). Следовательно, вы видите копию printf вывода еще раз.

1) Вы можете очистить его после каждого вызова printf(), используя fflush(stdout);

2) или используя \n, например:

  printf("2\n");

Другой способ - отключить буферизацию с помощью:

setbuf(stdout, NULL);

Ответ 2

Ваш анализ почти правильный. Тем не менее, printf не обязательно записывает сразу же дескриптор файла - вывод буферизируется внутри процесса. Второй процесс выполняет fork после помещения 2 в буфер. Второй и третий процессы будут иметь его в буфере и напечатать 2.

Если вы сделаете printf("2\n"), вместо этого новый символ линии заставит printf сбросить буфер, и вы увидите только один 2.