当前位置: 技术问答>linux和unix
linux中dup()与dup2()问题
来源: 互联网 发布时间:2017-04-05
本文导语: #include #include int main(){ int fd=dup(1); close(1); printf("hahan"); dup2(fd,1); printf("hellon"); return 0; } 运行结果: haha hello 程序先复制标志输出文件描述符到3,然后关闭标准输出文件描...
#include
#include
int main(){
int fd=dup(1);
close(1);
printf("hahan");
dup2(fd,1);
printf("hellon");
return 0;
}
运行结果:
haha
hello
程序先复制标志输出文件描述符到3,然后关闭标准输出文件描述符1,这时不应打印出"haha",为什么运行后会打印呢- -
另外,若是在close(1)之前添加一行printf("%dn",fd);输出就会变成
3
hello
这又是为啥?
求大侠指点,请尽可能从原理上解释--谢谢
#include
int main(){
int fd=dup(1);
close(1);
printf("hahan");
dup2(fd,1);
printf("hellon");
return 0;
}
运行结果:
haha
hello
程序先复制标志输出文件描述符到3,然后关闭标准输出文件描述符1,这时不应打印出"haha",为什么运行后会打印呢- -
另外,若是在close(1)之前添加一行printf("%dn",fd);输出就会变成
3
hello
这又是为啥?
求大侠指点,请尽可能从原理上解释--谢谢
|
猜测:
不知道标准I/O内部是如何处理这种fd错误的,printf("haha")语句执行时应该并没有输出,
如果只是将其忽略,然后缓冲区的内存不变的话,则在后面dup2(fd,1)后,printf("hello")时缓冲区的再次被输出。
证明方式:
1.在程序开始加上setbuf(stdout, NULL),将stdout设置为无缓冲,则printf("haha")字符串就不可能保留到后面了。试验结果如果不再输出haha了。,则猜测是对的。
至于为什么在close(1)前加上printf("%dn",fd)的问题,,我再进一步猜测下,stdout的初始化可能是一种懒惰法,即第一次调用函数时才初始化。 所以可能第一次初始化时如果fd 1 错误,输出会被保存到缓冲中,而后面如果fd错误,则输出不会被保存到缓冲中,所以这时haha不输出了。
证明方法:将printf("%dn",fd)改为printf("%d",fd);
看看输出是否为3,haha,hello...或者是3,hello,,或者是hello. 估计会是第一种情况或者第3种情况。
暂时没法试验。你可以试验下吧。
总之,这种异常情况下的行为应该和**具体的实现**有关,程序中不应该依赖于这些试验出来的不靠谱的结果。
要得到确切的原因,你可以从glibc库的标准I/O实现的源码中找到答案。。
不知道标准I/O内部是如何处理这种fd错误的,printf("haha")语句执行时应该并没有输出,
如果只是将其忽略,然后缓冲区的内存不变的话,则在后面dup2(fd,1)后,printf("hello")时缓冲区的再次被输出。
证明方式:
1.在程序开始加上setbuf(stdout, NULL),将stdout设置为无缓冲,则printf("haha")字符串就不可能保留到后面了。试验结果如果不再输出haha了。,则猜测是对的。
至于为什么在close(1)前加上printf("%dn",fd)的问题,,我再进一步猜测下,stdout的初始化可能是一种懒惰法,即第一次调用函数时才初始化。 所以可能第一次初始化时如果fd 1 错误,输出会被保存到缓冲中,而后面如果fd错误,则输出不会被保存到缓冲中,所以这时haha不输出了。
证明方法:将printf("%dn",fd)改为printf("%d",fd);
看看输出是否为3,haha,hello...或者是3,hello,,或者是hello. 估计会是第一种情况或者第3种情况。
暂时没法试验。你可以试验下吧。
总之,这种异常情况下的行为应该和**具体的实现**有关,程序中不应该依赖于这些试验出来的不靠谱的结果。
要得到确切的原因,你可以从glibc库的标准I/O实现的源码中找到答案。。