【Linux Kernel 进程管理】深入分析fork

本文详细剖析了fork系统调用的过程,包括其返回值的误解、内核函数_do_fork()的执行流程、PID的管理和子进程的调度等关键环节,并预告了后续将深入探讨copy_process函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这部分系列文章,从fork,vfork,clone三个系统调用入手,深入分析其过程,最后是总结和对比。每个系统调用可能需要好几篇文章,有空就来写写,希望能与各位互相交流学习。

首先是fork,很熟悉的一个系统调用,短短几行,一个“崭新”的进程就出现了。


 

一、 解释一下fork返回值: 返回两个值的概念和fork()的返回完全不同,例如return [res1,res2],而fork()真的只返回一个值:当前进程在当前命名空间的pid值。


为何出现返回两个值的幻觉,先简单说一下,函数的返回一般是通过寄存器例如eax。子进程创建成功后,会继续执行接下来的代码,父进程的eax写0,子进程的eax写pid,相当于两个进程分别读取各自的eax(这里的eax是虚拟给进程的,而不是真是的eax,毕竟eax只有一个),当然会有两个不同的值了。具体的细节以后遇到再阐述。

 

二、 fork,最终执行的内核函数是_do_fork(),这篇文章只介绍与fork相关的


可以看到,clone_flags只有SIGCHLD,这个信号是当子进程结束时,通知父进程的,如果父进程对SIGCHLD置之不理,就会产生僵尸进程。如果父进程结束,僵尸进程也会消失,不是因为他自觉消失了,而是用户态进程老大init完成了他父进程本该完成的工作。

三、_do_fork()


各种参数以后再说,因为fork只是把CIGCHLD标志位置1,其他参数都为空。

四、 首先申明需要的结构体指针,trace类型,和最后要返回的Pid值,很直观。


五、 fork的核心,copy 下一篇展开详细的分析。


六、 task_struc复制结束之后,设置trace,获取pid。


       主要是获取已经分配给子进程的PID实例,然后通过pid_vnr获取对应的pid数值,这

里有一点就是,对于PID实例,有get 和put操作肯定是成对出现的,get会增加此pid的引用计数,而put相反,用于内存回收,不然会造成内存泄漏。

七、子进程加入调度队列,fork返回。可以看到返回之前,子进程已经加入调度了,所以解释了为什么return的值不同

 


到此为止,整个fork就结束,看起来很简单,但是…水还很深,列举几个可能存在的疑问:

(1)     trace是干什么用的?

(2)     PID为什么是一个结构体,不应该是一个数值吗?

(3)     copy_process到底都做了什么事?

 这些问题每一个都能说好多,所以只能是慢慢来了,下一篇先展开copy_process。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值