Подтвердить что ты не робот

Fork() и выход

У меня есть простая программа:

int main()
{
    std::cout << " Hello World";
    fork();
}

После выполнения программы мой вывод: Hello World Hello World. Почему это происходит вместо одного Hello world? Я предполагаю, что дочерний процесс повторяется за кулисами, а выходной буфер распределяется между процессами или чем-то рядом с этими строками, но является ли это случаем или что-то еще происходит?

4b9b3361

Ответ 1

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

Этот происходит только потому, что cout буферизируется IO. Если вы использовали cerr, который не буферизирован, вы должны видеть сообщение только один раз, pre-fork.

Ответ 2

стандартный вывод использует буферизованный IO. Когда вызывается fork(), стандартный вывод не очищается, и буферизованный контент реплицируется в дочернем процессе. Эти буферы очищаются при выходе из процесса, в результате чего вы видите два выхода.

Если вы измените программу на:

std::cout << " Hello World;" << std::endl;

вы должны увидеть только один.

Ответ 3

Потому что вы вызвали fork(), не сбрасывая сначала все буферы.

cout.flush();
fork();

Ответ 4

Код для вывода "Hello World" выполняется только один раз. Проблема в том, что выходной буфер не сбрасывается. Поэтому, когда вы форкируете процесс, "Hello World" все еще сидит в выходном буфере. Когда обе программы выходят, их выходные буферы будут сброшены, и вы увидите результат дважды.

Самый простой способ продемонстрировать это - добавить новую строку в конце строки, которая вызовет неявный флеш или явно скроется с std::cout.flush();. Затем вы увидите только один выход.

Ответ 5

Если вы используете:

std::cout << " Hello World" << std::flush;

Вы видите только один. Я думаю, fork() копирует любой выходной буфер std::cout, который записывает.

Ответ 6

Строка не сразу записывается на экран; вместо этого он записывается во внутренний буфер. Детский процесс наследует копию выходного буфера, поэтому, когда дочерний элемент cout автоматически очищается, на экран выводится текст Hello World. Родитель также печатает Hello World.

Если вы сбросили cout до fork(), проблема почти наверняка исчезнет.

Ответ 7

Причина в том, что при вызове std::cout<< он действительно не выполняет сам вывод, но данные остаются в буфере в системе. Когда вы делаете вилку, копируются как код, так и данные, а также все связанные буферы. Наконец, и отец, и сын смывают их до стандартного вывода, и, таким образом, вы видите, что результат дублируется.

Ответ 8

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