进程调度案例分析与常见疑惑2:为啥fork之后有两个返回值?

微信公众号:奔跑吧linux社区


本文节选自《奔跑吧linux内核》第二版卷1第7.3.6

在用户空间可以使用fork()接口函数来创建一个用户进程,或者使用clone()接口函数来创建一个用户线程,它们在内核空间都是调用_do_fork()函数来实现的。读者常常会对_do_fork()函数的返回感到疑惑,例如以下两个问题。

1. 以fork()接口函数为例,为什么会有两次返回?其中父进程的返回值是子线程的PID,而子进程返回0。子线程是如何返回0的?
2. 子进程第一次返回用户空间时,它是返回到哪里?

对于第一个问题,在调用_do_fork()函数创建子进程后,子进程也会加入内核的调度器里,在调度器中参与调度。子进程会在稍后时刻得到调度和执行,因此fork()函数会有两次返回,一次是父进程的返回,另一次是子进程被调度执行后的返回。

另外,在copy_thread()函数里会复制父进程struct pt_regs栈框的全部内容到子进程的栈框里,这个栈框描述内核栈上保存寄存器的全部信息,以ARM64架构为例,包括X0~X30寄存器、栈指针寄存器、PC寄存器以及PSTATE寄存器等信息。另外,copy_thread()函数还会修改子进程的栈框中X0寄存器的值为0,因此在返回用户空间时子进程的返回值就是0,通过X0寄存器来传递返回值。
copy_thread()函数的代码片段如下。

<arch/arm64/kernel/process.c>

1     int copy_thre
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值