Вывод вашей программы сильно зависит от реализации.
Стандартная библиотека C применяет буферизацию к выходному потоку. Это означает, что он накапливает символы для записи до тех пор, пока буфер не достигнет определенной длины (или пока не будет выполнено определенное условие), а затем выводит весь текст сразу.
Наиболее распространенным поведением является использование буферизация строки , что означает, что текст будет распечатан при обнаружении символа новой строки (\n
). Это действительно то, что происходит на моей машине с вашим примером. Поскольку вы fork()
до printf()
, два процесса выполняют вызов, и выходные данные сразу же выводятся на печать, так как есть новая строка:
$ ./prog
Inside i= 0
Inside i= 0
Другой fork()
затем выполняется на каждом из двух процессов, но больше ничего не нужно выводить на печать, поскольку внутренний буфер вывода уже очищен, поэтому в этом случае ничего не происходит.
Однако, в зависимости от вашей конкретной реализации c и условий, в которых программа запущена, printf()
(и вообще любая функция stdio
) может решить применить другие правила буферизации.
Например, при передаче вывода в другую программу или в файл, glib c обычно использует буфер фиксированного размера и не выполняет буферизацию строки. Поскольку буфер не заполнен одним коротким printf()
, текст сохраняется внутри него для последующей печати. Когда вы fork()
второй раз, каждый из новых потомков получает копию указанного буфера, и весь текст затем печатается (каждым из них), когда процесс завершается. В моей системе при выводе по конвейеру это вывод:
$ ./prog | cat
Inside i= 0
Inside i= 0
Inside i= 0
Inside i= 0
Если вы хотите убедиться, что текст печатается сразу, вы можете использовать fflush()
или отключить буферизацию stdout
с setvbuf()
.
Примеры:
Использование fflush()
:
void create()
{
fork();
printf("Inside i= %d \n", i);
fflush(stdout);
i = i + 1;
fork();
}
Использование setvbuf()
:
int main()
{
setvbuf(stdout, NULL, _IONBF, 0);
create();
return 0;
}