[解决办法] APUE讲了 standard output is line buffered if it's connected to a terminal device; otherwise, it's fully buffered. [解决办法]
[解决办法] 实例 程序8 - 1例示了f o r k函数。如果执行此程序则得到: $ a . o u t a write to stdout before fork pid = 430, glob = 7, var = 89 子 进 程 的变量值改变了 pid = 429, glob = 6, var = 88 父 进 程 的变量值没有改变 $ a.out > temp.out $ cat temp.out a write to stdout before fork pid = 432, glob = 7, var = 89 before fork pid = 431, glob = 6, var = 88 一般来说,在f o r k之后是父进程先执行还是子进程先执行是不确定的。这取决于内核所使用的 调度算法。如果要求父、子进程之间相互同步,则要求某种形式的进程间通信。在程序8 - 1中, 父进程使自己睡眠2秒钟,以此使子进程先执行。但并不保证2秒钟已经足够,在8 . 8节说明竟 争条件时,还将谈及这一问题及其他类型的同步方法。在1 0 . 6节中,在f o r k之后将用信号使父、 1 4 2 U N I X环境高级编程 下载 子进程同步。 注意,程序8 - 1中f o r k与I / O函数之间的关系。回忆第3章中所述,w r i t e函数是不带缓存的。 因为在f o r k之前调用w r i t e,所以其数据写到标准输出一次。但是,标准I / O库是带缓存的。回 忆一下5 . 1 2节,如果标准输出连到终端设备,则它是行缓存的,否则它是全缓存的。当以交互 方式运行该程序时,只得到p r i n t f输出的行一次,其原因是标准输出缓存由新行符刷新。但是 当将标准输出重新定向到一个文件时,却得到p r i n t f输出行两次。其原因是,在f o r k之前调用了 p r i n t f一次,但当调用f o r k时,该行数据仍在缓存中,然后在父进程数据空间复制到子进程中时, 该缓存数据也被复制到子进程中。于是那时父、子进程各自有了带该行内容的缓存。在e x i t之 前的第二个p r i n t f将其数据添加到现存的缓存中。当每个进程终止时,其缓存中的内容被写到 相应文件中。 [解决办法] 就你代码而言在不是重定向下的情况下遍执行printf,由于遇到"\n"此时是stdout ,在默认下它是行缓冲的,遇到"\n"就立即把缓冲区内容写到屏幕,自然在执行printf后就之前立刻写掉了,自然fork后父子进程都不会再打印了。 而你重定向的时候缓冲类型就变成全缓冲了,执行printf后缓冲区没满或者没有执行fflush是不会写入文件的,自然fork后库函数中的缓冲区是有字符的,而此时是2个进程了!在进程退出时会执行exit操作,此操作2个目的,1.执行关闭所有输入输出流,在关闭之前执行fflush!,然后执行_exit程序终止,所以准确的说文件中的2个“OK\n”是程序退出时写上去的。 此外: 库函数缓冲区的三种类型: 全缓冲,行缓冲,无缓冲,默认情况下文件的缓冲是全缓冲的,stdout行缓冲的,而stderr是无缓冲的。 因此把您的程序“OK\n”改成“OK” int main() { printf("OK"); fork(); return 0; } 不管是用不用重定向 都会打出2个 OK