dup2后的奇异现象,该如何解决
dup2后的奇异现象
我写了这样一个程序:
本来期待程序运行时会把"hello\n"写入到文件file中,把"world\n"输出到屏幕上,但结果却是都在屏幕上。如果没有倒数第四行的dup2函数调用,就会都写入到文件file中。
跟踪系统调用的结果发现两个printf的输出的字符串内容被合在一起调用的write。也就是说,printf遇到\n并没有清缓冲。
但更奇怪的问题在于,只要在main函数中第一个dup2调用之前的任何一行插入一个printf调用,后面的输出就不会合并,而是像我先前预期的那样把"hello\n"写入到文件file中,把"world\n"输出到屏幕上了。
求高手解惑!
环境:ubuntu和fedora都是如此。
------解决方案--------------------
怀疑是标准输出重定向到文件中之后,缓冲方式由原来的行缓冲变为了全缓冲
------解决方案--------------------
我写了这样一个程序:
- C/C++ code
#include <stdio.h> #include <fcntl.h> #include <unistd.h> int main( ) { int fd = open("file", O_CREAT|O_WRONLY, 0644); int newfd = dup(1); dup2(fd, 1); close(fd); printf("hello\n"); dup2(newfd, 1); printf("world\n"); return 0; }
本来期待程序运行时会把"hello\n"写入到文件file中,把"world\n"输出到屏幕上,但结果却是都在屏幕上。如果没有倒数第四行的dup2函数调用,就会都写入到文件file中。
跟踪系统调用的结果发现两个printf的输出的字符串内容被合在一起调用的write。也就是说,printf遇到\n并没有清缓冲。
但更奇怪的问题在于,只要在main函数中第一个dup2调用之前的任何一行插入一个printf调用,后面的输出就不会合并,而是像我先前预期的那样把"hello\n"写入到文件file中,把"world\n"输出到屏幕上了。
求高手解惑!
环境:ubuntu和fedora都是如此。
------解决方案--------------------
怀疑是标准输出重定向到文件中之后,缓冲方式由原来的行缓冲变为了全缓冲
------解决方案--------------------
- C/C++ code
#include <stdio.h> #include <fcntl.h> #include <unistd.h> int main( ) { printf("start\n"); int fd = open("file", O_CREAT|O_WRONLY, 0644); int newfd = dup(1); dup2(fd, 1); close(fd); printf("hello\n"); dup2(newfd, 1); printf("world\n"); return 0; }
------解决方案--------------------
- C/C++ code
When the first I/O operation occurs on a file, malloc(3) is called, and a buffer is obtained. If a stream refers to a terminal (as stdout normally does) it is line buffered. The standard error stream stderr is always unbuffered by default.
------解决方案--------------------
楼上正确, ,
应该是由行缓冲变为了全缓冲。
验证如下:
至于你说的在第二个dup2前加个printf的话,hello 输出到文件,world输出到屏幕 的事。。 我试验了仍然是都输出到屏幕 。使用的环境是ubuntu 12.04 LTS.
理解这个行缓冲和全缓冲就行了。 不用太纠缠于太细节的东西 , 因为有些是和实现有关的。 若标准未规定, 则和各自的实现有关 (glibc库的实现)
- C/C++ code
#include <stdio.h> #include <fcntl.h> #include <unistd.h> int main( ) { int fd = open("file", O_CREAT|O_WRONLY, 0644); int newfd = dup(1); dup2(fd, 1); close(fd); setlinebuf(stdout); printf("hello\n"); dup2(newfd, 1); printf("world\n"); return 0; }