Маленькая задачка для C программистов

Мой коллега Александр Сортов поделился маленькой задачкой для C программистов:
Попробуйте без компьютера сообразить, сколько слов «before» и «after» будет напечатано после выполнения этого кода?

#include <stdio .h>
 
int main() {
  int pid;
  printf("before");
  pid = fork();
  printf("\nafter");
  if(pid == 0) {
    _exit();
  }
  printf("\n");
}
</stdio>


На первый взгляд, печатается «before», далее из одного процесса получаются два, оба они печатают «after». Всё не так просто — «before» может остаться в буфере и напечататься в обоих процессах. И наоборот, один из «after» так и останется в буфере, когда процесс завершится вызовом _exit().
Так что возможен и строго обратный результат — два «before» и один «after» 🙂

Я попался на первоначальную версию, ответив 1 и 4:

#include <stdio.h>
 
int main() {
printf("\nbefore");
fork();
fork();
printf("\nafter");
}

25.07.2007  Метки:   Рубрики: Разработка, Языки

2 комментария

  1. Evgeny Sergeev - 18.09.2007

    «Всё не так просто — “before” может остаться в буфере и напечататься в обоих процессах. И наоборот, один из “after” так и останется в буфере, когда процесс завершится вызовом _exit().»

    Это выходит за рамки моего понимания. 🙁 Не совсем понятно о каком буфере идет речь. И как дочка может выполнить код явно пренадлежащий родителю.

  2. allex - 19.09.2007

    Имеется ввиду буфер ввода-вывода процесса. printf не гарантирует реального вывода данных в поток, они могут накапливаться в буфере. Для принудительного сброса буфера есть функция flush.
    Буфер ввода-вывода как и все данные процесса, копируется при создании нового процесса при вызове fork. Дочка код не выполняет, а получает от родителя буфер с данными.
    Ну, с _exit, надеюсь, понятно — процесс завершается без сброса содержимого буфера.

Написать комментарий