fork函数的两次返回和父子进程的执行顺序简介

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,
              unsigned long stack_start,
              struct pt_regs *regs,
              unsigned long stack_size,
              int __user *parent_tidptr,
              int __user *child_tidptr)
在do_fork函数中又调用了copy_process函数,在这个函数里面,先用位图法的方式给新进程分配一个pid,然后再为新进程分配PCB资源,先将新进程要复制父进程的资源复制到它的PCB中,然后再为其PCB中的其他变量赋值。一般当一个进程的PCB创建好了,这个进程也就存在了,那么此时已经存在两个进程了,一个是父进程,一个是新创建的子进程,子进程若执行则返回0,父进程执行则返回子进程的pid。所以两次返回,指的是子进程和父进程各返回了一个值。

对于父子进程执行顺序的问题:也是在do_fork函数中,它会有一个标志性的变量,根据其不同取值,来决定先让谁执行,比如子进程先执行然后再把父进程插入到队列中,具体位置我也没研究清楚,简单来说就是在内核的实现过程中,父子进程的执行顺序还是由程序本身来决定的,但是到了用户态看起来就是随机的了。

以上是我个人在看了资料后的理解和总结,可能在细节方面有些问题,欢迎大家指正!


  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值