发新话题
打印

操作系统高手快来看!

操作系统高手快来看!

这是我在unix操作系统设计课上遇到的一个问题,连老师都没有解决,
问题出自Maurice J.Bach的《UNIX操作系统设计》第7章习题第一题,如下:
在一个终端上运行下面的程序,将它的标准输出重定向到一个文件,并比较结果。
main()
{
printf("hello\n");
if(fork()==0)
printf("world\n");
}
我试了一下,输出到终端的结果为:
hello
world
若重定向到文件,则结果为:
hello
world
hello

请问一下,为什么会这个样子呢?
这个问题可是难住了几十口子人,如果谁能解决,那你的水平,――――
望不吝赐教!:confused:       

TOP

hehe~~~这个问题连我菜鸟都会,你们老师是胡涂一时了。
你输出hello后,由于缓存还在所以出现这种情况,
你在第一个printf后加fflush(stdout)就不会这样了。      

TOP

Oh, It looks sooooo strangs, but when redirecting output to a terminal, stdout is buffered line by line -- that is, once you do a putchar('\n') or equivalent,the buffer is written to standard output with a "write(1, ...)". However, when stdout is redirected to a file, the stdio library buffers on a coarser scale -- not writing until some large buffer (probably 4K or 8K characters) is full. Thus, at the time of the fork() call, the "hello" string has not been written to fd=1. Instead, it has been buffered in the standard I/O library. That buffer is part of the program's address space, and is thus copied to the child process when fork() is called. Thus, when the bytes are finally flushed from the buffer, the "hello" string is written to the file twice. This is an important thing to realize. It looks strange but has a logical explanation.

See http://www.cs.utk.edu/~plank/pla ... s/Fork/lecture.html for details.

BTW, you can modify your program to following lines and ... )

#include <stdio.h>
mian ()
{
    printf("hello\n");

    if ( fork() == 0 ) {
        printf("world\n");

    printf("hello again\n");

}      
darncat

TOP

我做了你的实验,重定向的输出结果是,
hello
hello
world
应用到以下原理
1. printf 是缓冲输出.即不是直接写到标准输出而是先写到缓冲区中在缓冲区满的时候或者调用fflush时在写到标准输出. 当stdout是屏幕时,遇到'\n'就从缓冲区输出到屏幕
2. fork产生子进程时,几乎完全拷贝父进程.包括标准输出描述符和缓冲区
3. hello是父进程的输出,后面的hello是子进程拷贝父进程的缓冲区所造成的输出,world是子进程的输出,


"hehe~~~这个问题连我菜鸟都会,你们老师是胡涂一时了。
你输出hello后,由于缓存还在所以出现这种情况,
你在第一个printf后加fflush(stdout)就不会这样了。"

第一位仁兄只讲其然而不讲其所以然,也许跟没说一样.

后一位仁兄解释的很透彻.英文水平也好

我的解释主要想说我的实验结果和你的不一样. 实践是检验真理的唯一标准      

TOP

发新话题