2012-05-22 2 views
6

Я экспериментировал с fork() и перенаправлял, чтобы проверить, применяются ли повторные указания, сделанные родителем, и к ребенку. Я написал следующую простую программуЗаявление перед печатью 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? является печать дважды даже если он появляется много до fork() называется и должен только один раз печатается родителем.

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

+0

Я не уверен в этом, но убедитесь, что вы сбросили io-буферы перед вилкой. возможно, буферы будут скопированы для ребенка. – lupz

+2

Это сделало бы отличный вопрос для интервью! – dasblinkenlight

ответ

10

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

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

+0

Я знаю, что '\ n' не работает как автоматическая flusher после перенаправления. Спасибо и +1 –

+0

Вы также можете использовать 'setvbuf' для перенастройки' stdout'. –

3

Это из-за буферизации. Сделайте fflush сразу после printf.

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

+0

Если я изменяю 'exit()' на '_exit()', ребенок ничего не печатает. т.е. 'I AM CHILD' отсутствует на выходе. В чем разница между 'exit()' и '_exit()'? –

+1

@Stacker '_exit' не очищает буферы stdio. – cnicutar

1

промывка буфера решит проблему. использовать fflush сразу после печати.

0

Похоже, что ERROR! WHY DONT U UNDERSTAND по-прежнему буферизуется после форкирования и записывается обоими процессами.

Если добавить

fflush(stdout); 

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

 Смежные вопросы

  • Нет связанных вопросов^_^