当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 1 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 终于解决了有关fork()问题
帖子发表于 : 2009-10-18 19:19 

注册: 2009-09-26 1:51
帖子: 16
送出感谢: 0 次
接收感谢: 0 次
UNIX中创建进程的函数fork(),其基本机制是很明了的,但是我在某些方面有些疑问。
fork()函数父进程返回子进程的pid,对子进程返回0,错误返回-1。
下面是经典例子:
pid=fork();
if(pid==-1)
{
printf("Error\n");
exit(0);
}
else if(pid==0)
{
printf("I am child process, pid is %ld\n",(long)getpid());
exit(0);
}
else
{
printf("I am parent process,pid is %ld\n",(long)getpid());
exit(0);
}

这样会打印两行出来。说明父子进程是同时存在,执行顺序是随机的。
但是如下的程序我就有疑问了:
fork();
fork();
fork();
putchar('A');
打印出了
AAAAAAAA
然后改成
fork();
fork();
putchar('A');
fork();
同样也是打印
AAAAAAAA
那么父子进程到底是从哪里开始执行的???如果还是按顺序执行,那么第一段程序中三个fork(),就会产生八个进程,然后打印八个A,这很正常,但是跌入个为什么还是打印八个A呢????
我开始的猜想是,一个程序执行后,他会统计所有的fork信息,也就是说将所有的进程产生完毕后,在共享代码,即打印A,这样无论fork()出想在程序的何处,有几个进程,就会将这个程序执行多少遍。但是,我弄不清楚,程序是如何统计出fork()信息的,难道是在编译链接阶段????明显说不通啊!
于是继续找答案,找到下面代码:
printf("fork!\n");
pid=fork();

if (pid < 0)
printf("error in fork!");
else if (pid == 0)
printf("i am the child process, my process id is %dn",getpid());
else
printf("i am the parent process, my process id is %dn",getpid());
结果是:
fork!
i am the child process, my process id is 8971
i am the parent process, my process id is 8970

fork!只输出了一次!!!!!!!!!!!!!!
照我的推想,所有进程都会从头执行代码的话,这种结果是不可能出现的!
原来我犯了一个大错,没有考虑到putchar()这个函数的特殊性。putchar()这样的字符函数,它会将字符放在缓冲区中,这样每次fork()后,进程都继承了缓冲区,就会把缓冲区中的内容输出,造成了假象。
如下程序就足以说明问题了:
printf("A\n");
fork();
printf("B\n");
fork();
输出:
A
B
B
可见,这样的程序中,遇到fork(),进程分叉,但是没有继承缓冲区,故而还是顺序执行的,而非每个程序都从入口开始执行起。
个人以为,几乎所有的*nux编程书籍都用开始的那段代码,但是又都不说明缓冲区,这点很是不妥。只需稍加说明,便可以少去很多问题了。


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 1 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译