7-13进城控制--加载和执行进程

文章详细介绍了fork和exec两个系统调用在进程执行中的作用。fork创建子进程并复制父进程的地址空间,而exec则用新程序替换当前进程的代码和数据。文章提到了exec后,原进程的代码段、数据段、堆和栈都会被新程序覆盖。针对fork的效率问题,文章提出了vfork和copy-on-write(COW)两种优化方案,其中COW允许按需复制内存,提高了fork的效率。

前面少了一节课7-12

exec是想让当前进程执行新的程序,当他执行新的程序后,所有地址空间的代码、数据都已经变成新的程序里面存的内容了。

可以看上述代码,fork之后,fork返回值是-1,代表是当前执行的地址空间是在指定的地址空间执行的,接着就会执行exec,

需要注意的是,后面还有一句,printf("Why would I execute?"),为什么还有这个呢? 这个其实放在这是做一个提醒作用, 就是说如果你执行了exec这个系统调用之后,其实当前这个子进程的地址空间里面代码段已经被覆盖了,也意味接下来这条语句(printf("Why would I execute?"))代码的内容已经被新的程序,比如说calc计算器c程序覆盖了,其实这句话根本执行不到,所以在这写这句话,如果执行到,肯定是出了什么问题,比如exec失败了。

如果这个pid是大于0的,意味着在父进程空间。

需要注意的是最后有一个wait,后面会讲到,等待子进程结束,因为这个pid,大于0,其实就是代表子进程的pid号,假设wait返回了,也就意味着子进程结束了,

但是上面else这句话有没有漏洞呢?pid的fork返回值有3种状态,大于0,小于0,等于0

当else这句话执行的时候,其实有两种情况,小于或者大于,应该更细化,如果小于0,意味着fork是失败的系统调用,应该提示error,而如果是pid>0,则执行老的else里面的内容。

执行fork之后,代码和数据都复制了一份,

执行exec的时候pid没变,但是他里面的代码是变了,但是里面执行的代码是变了,从本来的程序变成了/bin/calc 这个程序里面的代码内容,

下面是实际内存中的布局图:

下图是执行fork

下图是执行完exec后,可以看到PCB信息有变化,另外内存空间有很大的变化,因为它栈段完全被这个新的程序所替换,而且也是从calc的main函数开始执行。

执行exec的时候,这个进程本身的代码段、数据段、堆、和栈都会被覆盖,

还要关注下fork的执行开销,因为在程序执行过程中会创建很多的进程,我们观察到一点,执行fork的时候,接下来99%都会执行exec,就意味着,我们创建一个新的进程,更多的是让它执行不同的程序,这里面有一些值得优化的地方,fork是要把父进程的地址空间完全复制一份到子进程中来,这里有一个内存的大量拷贝,需要把代码段数据段全都拷贝到另一进程地址空间中去,但是接下来执行exec的时候,你刚才所做的拷贝全都没有用,为什么呢?因为它要去还在新的程序,要把你这个代码段,数据段给重新覆盖掉,所以你前面做的fork的拷贝是多余的。

优化:

方法1:vfork,早期unix系统提供的一种手段,做fork的时候只是复制y一小部分,j绝大部分都没有复制,因为它知道调完vfork之后,我们的程序会紧接着调用exec,使得效率高。但是这个增加了编程人员的开销,增加了一个fork和vfork

方法2:编程人员还是只有fork一个系统调用就行了,而不需要考虑什么时候后面程序是执行exec还是不执行exec的系统调用好。结合之前讲的内存管理,其实操作系统里面,各个子系统之间是相互支持相互帮助的,我们通过虚存管理,就可以实现一个高效的fork实现机制,这里面有个技术叫copy on write (COW). 就是写的时候再进行复制,有了这个技术支持之后,我们fork的实现就高效很多。大致意思是,当父进程创建子进程的时候,如果是采用COW技术,我们在做实际的子进程地址空间复制的时候,并没有像之前一样把整个地址空间真实的复制,而只是复制,父进程地址空间所需要的元数据,这些元数据其实就是页表,他们指向同一块内存空间,当父进程或者子进程对某一个地址单元进行写操作的时候,会触发一个异常,使得无论是父进程还是子进程,要完成一个操作,就是把触发异常的这个页给他复制成两份,使得我们父进程和子进程分别有不同的地址。通过这种方式,可以实现按需的一种情况。按需写的一种情况复制,如果你全部做只读,我确实没必要复制。只有当写的时候,这个父进程和子进程有不同的页表。

方法2就很有效果,不管你后面执不执行exec,我们的fork第一她还是完全和之前的语义是一样的,第二执行效率很高,因为它只复制了跟着地址空间管理相关的所需要的元数据等等,但是它根据是否完成写操作来决定是否去复制

copy on write,是进程管理和内存管理之间的一个有效的相互支撑的一种机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值