昨天在做Linux实验的时候,后面的同学发现一个很差异的现象!废话不说,先贴代码!
就是简单的fork小程序,简化之后的代码如下:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> int main( int argc, char ** argv ) { pid_t pid; int ret; printf("I am parent ... \n"); ret = fork(); //!> fork the child switch( ret ) { case -1: printf("Error...\n"); exit( EXIT_FAILURE ); case 0: printf("I am child!\n"); break; default: break; } return 0; }这段代码貌似还是很正常的,在我的机子上的输出结果是:
pt@ubuntu:~/桌面$ gcc -o test test.c
pt@ubuntu:~/桌面$ ./test
I am parent ...
I am child!
再看下面差不多的代码:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> int main( int argc, char ** argv ) { pid_t pid; int ret; printf("I am parent ... "); //!> 看出这个地方不一样了吗? ret = fork(); //!> fork the child switch( ret ) { case -1: printf("Error...\n"); exit( EXIT_FAILURE ); case 0: printf("I am child!\n"); break; default: break; } return 0; }在我的机子上的输出是:
pt@ubuntu:~/桌面$ gcc -o test test.c
pt@ubuntu:~/桌面$ ./test
I am parent ... I am parent ... I am child!
输出了两个I am parent ... 是吧,按理说fork在复制的时候,parent顺序执行过的代码在chiled中应该是不会执行的呀!为什么呢?
当然这个结果肯定是OK的,这就要看printf的问题了,对于第一代码第一个printf结果在遇到'\n'就直接输出了,但是第二个不会,没有'\n',只会将结果保存在
printf的缓冲区,然后呀与后面的printf中的内容一起输出!!!所以fork在拷贝的时候,就将 parent的缓冲区一并拷贝过去,所以在第二个代码中看到的就是
那样的结果!呵呵!虽然是个小问题,但是还是值得去研究呀!还是回去再看看printf的实现机制吧,唉~~~
首先感谢zhy006指出错误,谢谢!
确实是自己的理解错了!这个地方涉及到的是行缓冲和全缓冲的问题!然后自己在网上搜了一下!给个差不多的链接!
点击打开链接
学艺不精!惭愧惭愧!
再来细细咀嚼一下:对于行缓冲来说就是:if遇到回车字符那么不管缓冲区有没有满都直接输出,if没有\n那么就会一直加到缓冲区直到一行满那么就会自动输出,不管有没有\n都会输出!
那么对于上面的代码:printf("I am parent ...");没\n,那么虽然是行缓冲,但是一行没有满,它的缓冲区内就还有当前的字符,然后我们知道fork时缓冲区被拷贝到child中,那么就是现在有两份这样的字符串!所以在输出的时候会有两个输出!!!
对于行缓冲区,我下面有一个代码的测试,其实也就是第一个代码的修改:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> int main( int argc, char ** argv ) { pid_t pid; int ret; printf("..onsdnvasldvjnasldkvnasldkvnasonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdlkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdvkasdvkalksvdnaskdvbasdvasdvnasldvkjasdvlaskdvnasdvnsadvskdvnalsdvasdvsd. "); //!> 此处改成足够长的字符串,以至于会没有\n的时候会输出一部分,然后还剩下一点点字符,会被拷贝到child中!Yes!!! ret = fork(); //!> fork the child switch( ret ) { case -1: printf("Error...\n"); exit( EXIT_FAILURE ); case 0: printf("I am child!\n"); break; default: printf("Parent too..\n"); break; } return 0; }
在我的机子上的输出:
pt@ubuntu:~/桌面$ gcc -o test test.c
pt@ubuntu:~/桌面$ ./test
..onsdnvasldvjnasldkvnasldkvnasonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbans
kdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdv
bjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjn
asdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasd
lvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkb
asvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasv
dasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdas
vdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdk
aksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaks
donsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdon
sdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdn
vasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasl
dvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvj
nasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnas
ldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkv
nasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnas
ldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkv
naslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnas
lkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjd
vnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvna
slkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkd
vnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvns
alkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkj
dvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsj
nvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnva
jlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlsk
vlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsj
kbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbd
vsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsal
kdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdv
nalskjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdonsdnvasldvjnasldkvnasldkvnaslkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnal
skjdvbsaldkvbansdvlkjbsndvlkjasnbdvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdlkjdvnaslkdvnsalkjdvsjnvajlskvlsjkbdvsalkdvnalskjdvbsaldkvbansdvlkjbsndvlkjasnb
dvlkjasnbvaskdvbanskdvbjnasdlvkbasvdasvdkaksdvkasdvkalksvdnaskdvbasdvasdvnasldvkjasdvlaskdvnasdvnsadvskdvnalsdvasdvsd. Parent too..
vsd. I am child!
看见没有!只有vsd.I am child! 也就是说,前面所有的字符个数满足一行的整数倍!所以没有\n也会输出,不会保存在缓冲区!所以最后只剩下vsd.几个字符!所以会显示两次哟!!!
呵呵呵~~~