5
回答
进程与程序问题,为什么是那个运行结果?
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

程序

#include <stdio.h>
main()
{int p1,p2,i;
while((p1 = fork()) == -1);
if(p1 == 0)
     for(i = 0; i < 4; i++)
       printf("daughter %d\n",i);
else
   {while((p2 = fork()) == -1);
     if(p2 == 0)
       for(i = 0; i < 4; i++)
         printf("son %d\n",i);
     else
     for(i = 0; i < 4; i++)
     printf("parent %d\n",i);  
   }
}   

在gcc下运行为什么是这个结果:                                                           

daughter 0
parent 0
daughter 1
parent 1
daughter 2
parent 2
daughter 3
parent 3
administrator@ubuntu :~/桌面$ son 0
son 1
son 2
son 3                                                                                     

哪位大哥大姐能解释一下

举报
鹏城二少
发帖于6年前 5回/286阅
共有5个答案 最后回答: 6年前

首先需要指出,你的printf名称有些问题。对应son 是没错的。对应 parent 应该是 grandson (孙子),对应 daughter应该是 myself。

fork 返回0后,任何对于这个返回判断为0 的条件分支都是自身执行的,其他分支自己不会被执行到。

这是简单的说。同时你的这个问题,引出了另外两个方面的问题。一个是fork vfork就是进程调用顺序的问题。另一个是共享资源,就是IO的处理问题。

同时你需要注意的是,当 administrator@ubuntu :~/桌面出现时,表示当初你启动的进程已经被退出,也就是myself部分都处理完了。其他fork出来的子孙,祖先会指向系统最初的一个进程。bash如果我没记错的话是exe一个程序。等程序结束后,自己才又活动。所以你会发现,存在

administrator@ubuntu :~/桌面 之后还有数据在输出。但这个输出的动作,并不是bash启动的那个进程的行为。

关于前面说的fork 。这里经常有一个提问,fork一个新进程,(所谓父子关系,是另一个话题),新进程和老进程谁先运行(且不谈任意进程时间,超过了OS的进程切换时间)。这个很难说,很多人讨论是随机的。但就我的理解,应该仍然是新进程先运行。因为存在个老版本的vfork。vfork的意思是,我创建的个进程,但肯定不会和目前进程有什么关系,会启动其他程序,由此,fork中的进程的上下文或资源的COPY动作,就变得多余,因此,出现了vfork。貌似现在的fork已经采用了vfork的方式,从man上所谓的 copy-on_writes。从这个角度我认为,现在的fork优先是子进程先运行,然后是父进程在运行。

而为什么你先printf出来你的daugther。我的理解是,你的son存在一个新的fork,这个涉及到系统资源问题,肯定是个堵塞的方式。由此,在你

while ((p2 = fork()) == -1) {}  处,子进程被挂起,父进程占了便宜,开始执行。

而为什么对于 son 和 grandson(我就不用你的名词了,免得混乱),并没有交替,而是 grandson 和myself的交替,这块只能确认son在最后处理,如果grandson myself在自身时间片内完成所有动作,而且没有挂起。因为父子关系的继承,OS只看一级父子,这样足够保证祖先的东西能被子孙继承下来。而不是动不动就判断祖先和子孙。

但是目前IO这块的资源和进程之间的对接,我的解释只能到IO存在原子操作。不过谁先强到,这个和进程调度算法,以及相互之间的防止死锁的资源互斥有关,静态分析,我也得不出动态的正确结论。

我觉得你将printf中间所有的 \n去掉,或许更有意思。我觉得没有\n,printf应该是个IO口独占的工作。这个我没有验证过。

另外,进程也好,线程也好,强调OS谁先运行谁后运行意义不大,绝大多数情况下没有意义。谁在谁前后,是由你的设计目标的逻辑给出的。通过各种进程堵塞方法,来保证进程间的同步,就是谁前谁后的问题。有心思去研究OS谁前谁后,只有一个目标,优化OS的进程管理算法,其他情况下都没有意义(研究的结果也是静态的)

--- 共有 7 条评论 ---
生命与幻觉回复 @中山野鬼 : 恩,好吧,但是还是谢谢了 6年前 回复
中山野鬼回复 @speakornow : 这块我现在手上没有设备,没办法做,但我真打算近期折腾。有些事情,不是想做就能做的。呵呵。特别是数据库,例如对大量数据的特殊化操作。没客户的数据,自己建的表,不太靠谱。 6年前 回复
生命与幻觉回复 @中山野鬼 : MySQL数据库的无缝迁移,我要从a机转到b机,但是b机上的mysql我又要加上一些table,主要是数据同步问题,这个有没有好的方案? 6年前 回复
中山野鬼回复 @speakornow : 。。。我又被GAY了。 6年前 回复
生命与幻觉严重怀疑你们两个搞基。。。 6年前 回复
顶部