Вопрос по c – Оператор перед fork () дважды печатает [duplicate]

6

This question already has an answer here:

printf anomaly after “fork()” 3 answers

Я экспериментировал сfork() и перенаправление, чтобы проверить, относятся ли перенаправления, выполненные в родителе, и к ребенку. Я написал следующую простую программу

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main ()
{
    freopen( "error.txt", "w+t", stdout ); // From now on, stdout = error.txt
    printf (" ERROR!  WHY DONT U UNDERSTAND?\n");
    if ( fork() == 0 ) 
    {   
        printf(" I AM CHILD\n");
        exit(0);
    }   
    else-
    {   
        printf (" EITHER I AM A PARENT OR SOMETHING GOT SCREWED\n");
    }   


    return 0;
}

Выход (error.txt ) Я получил это

ERROR!  WHY DONT U UNDERSTAND?
EITHER I AM A PARENT OR SOMETHING GOT SCREWED
ERROR!  WHY DONT U UNDERSTAND?
I AM CHILD

Удивительно,ERROR! WHY DONT U UNDERSTAND? являетсяprinting twice хотя это появляется намного раньшеfork() вызывается и должен быть напечатан только один раз родителем.

Может кто-нибудь пролить некоторый свет на это?

Я не уверен насчет этого, но убедитесь, что вы очистили буферы перед форком. возможно буферы копируются ребенку. lupz
Это сделало бы для превосходного вопроса интервью! dasblinkenlight

Ваш Ответ

4   ответа
10

reopen поток не является интерактивным, он полностью буферизован и не сбрасывается'\n', Доfork называется буфер все еще содержит сообщение, а послеfork это буферизованное сообщение было продублировано (поскольку оба процесса получили свои собственные копииstdout) и затем покраснел как родитель, так и ребенок. См. Часть 7.19.3 стандарта С.

Вы можете избежать такого поведения, позвонивfflush как раз передfork.

Я не знаю, что\n не работает как автоматический сброс после перенаправления. Спасибо и +1 Pavan Manjunath
Вы также можете использоватьsetvbuf перенастроитьstdout.
0

ERROR! WHY DONT U UNDERSTAND все еще буферизируется после разветвления и записывается обоими процессами.

Если вы добавите

fflush(stdout);

сразу после вашего первогоprintf() внутренний буфер очищается, и он появляется только один раз в вашем файле.

1

используйте fflush сразу после оператора print.

3

fflush сразу послеprintf.

Оба процесса заканчиваются одной и той же копиейstdioи оба приступают к его очисткеexit, Вы также можете предотвратить это, если позвоните_exit у ребенка.

@Stacker_exit не очищает буферы STDIO.
Если я изменюexit() в_exit()ребенок ничего не печатает. т.е.I AM CHILD отсутствует в выводе. В чем разница междуexit() а также_exit() ? Pavan Manjunath

Похожие вопросы