2012-05-22 22 views
6

fork() ile deneme yapıyordum ve üstte yapılan yeniden yönlendirmelerin de çocuk için geçerli olup olmadığını kontrol etmek için yeniden yöneliyordum. Ben ERROR! WHY DONT U UNDERSTAND?fork() denilen ve gerektiği önce baskı iki kez çok görünmesine rağmen, ben ŞaşırtıcıÇatal() iki kez yazdırmadan önce bildirim

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

olduğunu var

#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; 
} 

çıkışı (error.txt) Aşağıdaki basit program yazdım sadece ebeveyn tarafından bir kez basılabilir.

Bu konuda biraz ışık tutabilir mi?

+0

Bu konuda emin değilim, ancak io-tamponları, çataldan önce yıkadığınızdan emin olun. Belki de tamponlar çocuğa kopyalanır. – lupz

+2

Bu mükemmel bir röportaj sorusu yapar! – dasblinkenlight

cevap

10

reopen'dan sonra, akış etkileşimli değil, tam olarak arabelleğe alınmış ve '\n' numaralı ortamdan temizlenmiyor. fork çağrılmadan önce, arabellek yine de iletiyi içerir ve fork'dan sonra bu arabellek ileti çoğaltılmıştır (her iki işlem de kendi kopyalarını stdout'a sahip olduğu için) ve daha sonra hem ebeveyn hem de çocuk tarafından temizlenmiştir. C standardının 7.19.3 kısmına bakınız.

fork'dan hemen önce fflush numaralı telefonu arayarak bu tür davranışlardan kaçınabilirsiniz. Tamponun yıkanması, sorunu çözecektir

+0

Biliyorum, \ n \ yeniden yönlendirmeden sonra otomatik bir flush olarak çalışmıyor. Teşekkür ve +1 –

+0

Ayrıca 'stdout''u yeniden yapılandırmak için' setvbuf' kullanabilirsiniz. –

3

Arabellek nedeniyle. printf'dan hemen sonra fflush yapın.

Her iki işlem de stdio öğesinin dahili kopyasıyla sonlanır ve her ikisi de exit adresinden temizlemeye devam eder. Çocuğa, _exit numaralı telefonu arayarak, bunun olmasını engelleyebilirsiniz.

+0

'exit()' ile '_exit()' arasında değişiklik yaparsam, çocuk hiçbir şey yazdırmıyor. “Ben ÇOCUK” ​​çıktıdan eksik. 'Exit()' ve '_exit()' arasındaki fark nedir? –

+1

@Stacker '_exit' stdio arabelleklerini temizlemiyor. – cnicutar

1

. yazdırma ifadesinden hemen sonra fflush kullanın.

0

ERROR! WHY DONT U UNDERSTAND hala forkingden sonra arabelleğe alınmış ve her iki işlem tarafından yazılmıştır.

sağ ilk printf() iç arabellek aktarılmadan ve sadece dosyanıza bir kez görünür sonra

fflush(stdout); 

ekleyin.