文档章节

fork()两次不同返回值的实现

jackhen
 jackhen
发布于 2016/04/10 20:52
字数 1024
阅读 123
收藏 2

对于fork来说,父子进程共享同一段代码空间,所以给人的感觉好像是有两次返回,其实对于调用fork的父进程来说,如果fork出来的子进程没
有得到 调度,那么父进程从fork系统调用返回,同时分析sys_fork知道,fork返回的是子进程的id。再看fork出来的子进程,由
copy_process函数可以看出,子进程的返回地址为ret_from_fork(和父进程在同一个代码点上返回),返回值直接置为0。所以当子进
程得到调度的时候,也从fork返回,返回值为0。
关键注意两点:1.fork返回后,父进程或子进程的执行位置。(首先会将当前进程eax的值做为返回值)2.两次返回的pid存放的位置。(eax中)
进程调用copy_process得到lastpid的值(放入eax中,fork正常返回后,父进程中返回的就是lastpid)
子进程任务状态段tss的eax被设置成0,
fork.c 中
p->tss.eax=0;(如果子进程要执行就需要进程切换,当发生切换时,子进程tss中的eax值就调入eax寄存器,子进程执行时首先会将eax的内容做为返回值)
当子进程开始执行时,copy_process返回eax的值。
fork()后,就是两个任务同时进行,父进程用他的tss,子进程用自己的tss,在切换时,各用各的eax中的值.
所以,“一次调用两次返回”是2个不同的进程!
看这一句:pid=fork()
当执行这一句时,当前进程进入fork()运行,此时,fork()内会用一段嵌入式汇编进行系统调
用:int
0×80(具体代码可参见内核版本0.11的unistd.h文件的133行_syscall0函数)。这时进入内核根据此前写入eax的系统调用功能号
便会运行sys_fork系统调用。接着,sys_fork中首先会调用C函数find_empty_process产生一个新的进程,然后会调用C函数
copy_process将父进程的内容复制给子进程,但是子进程tss中的eax值赋值为0(这也是为什么子进程中返回0的原因),当赋值完成
后,copy_process会返回新进程(该子进程)的pid,这个值会被保存到eax中。这时子进程就产生了,此时子进程与父进程拥有相同的代码空
间,程序指针寄存器eip指向相同的下一条指令地址,当fork正常返回调用其的父进程后,因为eax中的值是新创建的子进程号,所以,fork()返回
子进程号,执行else(pid>0);当产生进程切换运行子进程时,首先会恢复子进程的运行环境即装入子进程的tss任务状态段,其中的
eax值(copy_process中置为0)也会被装入eax寄存器,所以,当子进程运行时,fork返回的是0执行if(pid==0)。
【NOTE5】
理解它关键在于理解堆栈的切换和压栈,弹栈!
关于子进程的返回:
子进程复制了父进程的栈内容,从高到低
SS
ESP
EFLAGS
CS
EIP —–此是int 0×80 的下一条指令,也是子进程开始执行的地方!!!!
DS
ES
FS
EDX
ECX
EBX
GS
ESI
EDI
EBP
EAX(0)
由于 EAX = 0,所以子进程返回 0 给 fork.
注:新进程的用户栈设为其父进程的用户栈(最后弹出的SS,ESP)。如果父子进程以copy_on_write方式共用用户堆栈
(Linux之下就是这样的),而且在此之前父进程修改了该堆栈(如果父进程先返回,这几乎是肯定的),那么,系统已经为父进程创建了该用户栈的副本,父进程原来的用户栈留给了子进程。那么新进程的系统栈已经清空,新进程回到了用户态,返回到了函数fork。


本文转载自:http://my.oschina.net/vazor/blog/85759

jackhen
粉丝 2
博文 39
码字总数 13207
作品 0
杭州
后端工程师
私信 提问
加载中

评论(1)

K
KevinJi
大哥,不起作用啊,Android studio 2.2 ,Android 5.1.1

暂无文章

arduino项目-1. 模拟楼道灯

@toc 1.1 情景说明 说明 漆黑的夜晚,当有人非法进入一所房屋,房屋内的灯在恰当的时间亮起,也许会有效阻止非法活动的继续。 效果展示 1.2 实验器材 器材名称 数量 继电器 1 人体红外感应器...

acktomas
29分钟前
4
0
Nacos 常见问题及解决方法

Nacos 开源至今已有一年,在这一年里,得到了很多用户的支持和反馈。在与社区的交流中,我们发现有一些问题出现的频率比较高,为了能够让用户更快的解决问题,我们总结了这篇常见问题及解决方...

阿里云官方博客
35分钟前
6
0
pinyin4j 满足中文转拼音的需求

引入依赖 // https://mvnrepository.com/artifact/com.belerweb/pinyin4j //汉字转拼音compile group: 'com.belerweb', name: 'pinyin4j', version: '2.5.1' 写入中文转拼英的工具......

edison_kwok
40分钟前
5
0
IPSE接入Substrate/Polkadot插槽实现互操作性的运行原理

Substrate框架将区块链的众多功能都模块化,对于开发者来说,只是一个选择的问题,同时还保持了众多的可以定制的功能和模块,比如底层通信模块,比如账户体系,比如共识机制等都是可以自己定...

IPSE
46分钟前
156
0
linux配置安装phpMyAdmin的步骤记录

1、首先在phpMyAdmin官方网站 http://www.phpmyadmin.net/downloads下载源码包,或者通过脚本之家进行下载://www.jb51.net/codes/405261.html ,下载后上传到服务器解压即可,或者通过Linux...

蜗牛女孩
47分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部