首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

dup2后的奇异现象,该如何解决

2012-06-13 
dup2后的奇异现象我写了这样一个程序:C/C++ code#include stdio.h#include fcntl.h#include unistd.h

dup2后的奇异现象
我写了这样一个程序:

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

热点排行