Рассмотрим следующий фрагмент кода:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int i;
for(i = 0; i < 2; i++)
{
fork();
printf(".");
}
return 0;
}
Эта программа выводит 8 точек. Как это может быть возможно? Не должно ли быть 6 точек вместо этого?
Ответы:
fork()
Примитив часто тянется воображение. Пока вы не почувствуете это, вы должны проследить на бумаге, что такое каждая операция, и учесть количество процессов. Не забывайте, что fork () создает почти идеальную копию текущего процесса. Наиболее существенным отличием (для большинства целей) является то, чтоfork()
возвращаемое значение отличается между родителем и ребенком. (Поскольку этот код игнорирует возвращаемое значение, это не имеет значения.)Итак, во-первых, есть один процесс. Это создает второй процесс, который печатает точку и цикл. На второй итерации каждый создает другую копию, поэтому четыре процесса печатают точку и затем завершают работу. Таким образом, мы можем легко объяснить шесть точек, как вы ожидаете.
Однако, что
printf()
действительно делает, так это буферизирует вывод. Таким образом, первая точка, когда было только два процесса, не появляется при записи. Эти точки остаются в буфере, который дублируется в fork (). Только когда процесс собирается завершиться, появляется буферизованная точка. Четыре процесса печатают буферизованную точку, плюс новый дает 8 точек.Если вы хотите избежать такого поведения, позвоните
fflush(stdout);
послеprintf()
.источник
fork()
не создает 2, затем завершает работу, он только создает еще 1 процесс.У вас есть незафиксированные буферы в выходных потоках . stdout буферизуется строкой, а буфер реплицируется вместе с остальной частью процесса. Когда программа завершается, незафиксированный буфер записывается дважды (один раз для каждого процесса). Оба используют
и
не выставляйте проблему
В первом примере вы создаете четыре процесса, каждый из которых имеет две точки в буфере выходного потока. Когда каждый поток завершается, он очищает свой буфер, генерируя восемь точек.
источник
когда я = 0
Process_1: буферизованный текст = 1 точка
Process_2 (созданный Process_1): буферизованный текст = 1 точка
когда я = 1
Process_3 (созданный Process_1): наследует 1 буферизованную точку из Process_1 и печатает 1 точку самостоятельно. Всего Process_3 печатает 2 точки.
Process_4 (созданный Process_2): наследует 1 буферизованную точку из Process_2 и печатает 1 точку самостоятельно. Всего Process_4 печатает 2 точки.
Process_1: печатает 2 точки (одна буферизованная точка, когда i = 0, и другая точка, когда i = 1)
Process_2: печатает 2 точки (одна буферизованная точка при i = 0 и другая точка при i = 1)
Окончательный результат: 8 точек. :)
источник