http://hi.baidu.com/%CE%A8%C0%D6ice/blog/item/c78270ff877db72d5c600889.html
今天为了参加腾讯的面试,特地研究了一下fork的两次返回。 大家都知道,调用fork后会返回两个值或者一个值。两个值是指在调用成功的情况下,返回0表示子进程在运行,大于0的数表示父进程在运行,错误情况下就返回一个值,一个小于0的值。在创建成功的情况下,子进程执行返回0,是因为一个子进程只有一个父进程,所以无需知道它父进程的id,通过getppid()也就可以获取它的值,而父进程运行时,它需要知道它的至此执行对应的子进程是哪个,因为一个父进程可能会有不止一个的子进程,而且在父进程中也没有可以直接获得其子进程pid的库函数。 下面就介绍fork的两次返回,一个函数的调用怎么会返回两个值呢,这里要强调的是,它不是返回了两个值,而是返回了两次,一次返回一个值,所以它还是符合函数返回值的特性---只能返回一个值。 fork()是一个经过封装的用户态函数,当用户程序调用了fork函数之后,执行系统调用sys_fork(),而在sys_fork()中直接调用了do_fork()函数,在do_fork()函数中有6个参数,关于参数,我暂不详解,因为我还没研究透。也就是说真正的创建进程实在do_fork函数中实现的,其实向vfork,pthread_creat也都是最终调用的do_fork函数,do_fork函数对调用它的函数的区别是通过clone_flags标志来实现的。 long do_fork(unsigned long clone_flags, 对于父子进程执行顺序的问题:也是在do_fork函数中,它会有一个标志性的变量,根据其不同取值,来决定先让谁执行,比如子进程先执行然后再把父进程插入到队列中,具体位置我也没研究清楚,简单来说就是在内核的实现过程中,父子进程的执行顺序还是由程序本身来决定的,但是到了用户态看起来就是随机的了。 以上是我个人在看了资料后的理解和总结,可能在细节方面有些问题,欢迎大家指正! |