2012-05-22 33 views
6

Tôi đã thử nghiệm với fork() và chuyển hướng để kiểm tra xem các chỉ đường lại được thực hiện trong phụ huynh có áp dụng cho trẻ không. Tôi đã viết chương trình đơn giản sau đâyTuyên bố trước khi in() in hai lần

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

Sản lượng (error.txt) tôi nhận được

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

Đáng ngạc nhiên, ERROR! WHY DONT U UNDERSTAND?in ấn hai lần mặc dù nó xuất hiện nhiều trước khi fork() được gọi và nên chỉ được in một lần bởi cha mẹ.

Có ai có thể làm sáng tỏ điều này không?

+0

Tôi không chắc chắn về điều này, nhưng chắc chắn rằng bạn xả io-bộ đệm, trước ngã ba. có lẽ các bộ đệm được sao chép vào đứa trẻ. – lupz

+2

Điều này sẽ làm cho một câu hỏi phỏng vấn tuyệt vời! – dasblinkenlight

Trả lời

10

Kể từ sau reopen luồng không tương tác, bộ đệm hoàn toàn được đệm và không tuôn ra trên '\n'. Trước khi fork được gọi là bộ đệm vẫn chứa thông báo và sau fork thư đệm này đã được sao chép (vì cả hai quá trình đều có bản sao riêng của chúng là stdout) và sau đó được xóa bởi cả cha và con. Xem phần 7.19.3 của tiêu chuẩn C.

Bạn có thể tránh hành vi như vậy bằng cách gọi fflush ngay trước fork.

+0

Tôi biết rằng '\ n' không hoạt động như máy nghiền tự động sau khi chuyển hướng. Cảm ơn và +1 –

+0

Bạn cũng có thể sử dụng 'setvbuf' để định cấu hình lại' stdout'. –

3

Đó là do bộ đệm. Thực hiện fflush ngay sau printf.

Cả hai quá trình đều có cùng một bản sao nội dung bên trong của stdio và cả hai đều tiến hành tuôn ra tại exit. Bạn cũng có thể ngăn chặn nó xảy ra nếu bạn gọi _exit ở trẻ em.

+0

Nếu tôi thay đổi 'exit()' thành '_exit()', con không in bất cứ thứ gì. tức là 'I AM CHILD' bị thiếu từ đầu ra. Whats sự khác biệt giữa 'exit()' và '_exit()' là gì? –

+1

@Stacker '_exit' không xóa bộ đệm stdio. – cnicutar

1

xả bộ đệm sẽ giải quyết được sự cố. sử dụng fflush ngay sau bản in.

0

Dường như ERROR! WHY DONT U UNDERSTAND vẫn được lưu vào bộ đệm sau khi tắt và được viết bởi cả hai quy trình.

Nếu bạn thêm

fflush(stdout); 

ngay sau khi printf() bộ đệm nội bộ đầu tiên của bạn là đỏ ửng và nó chỉ xuất hiện một lần trong tập tin của bạn.