进程的创建fork和vfork

1.写时拷贝

      传统的fork()系统调用直接把所有的资源复制给创建的进程。这种实现过于简单并且效率低下,因为它拷贝的数据也许并不共享,更糟的情况是,如果新进程打算立即执行一个新的映像,那么所有的拷贝都是白费的。linux的fork()使用写时拷贝页实现。写时拷贝是一种可以推迟甚至免除拷贝数据的技术。内核此时不复制整个进程空间,而是让父进程和子进程共享同一个拷贝。只有在需要写入的时候,数据才会被复制,从而使各个进程拥有各自的拷贝,在此之前,只是以只读的方式共享。在页不写入的时候,根本无需复制,例如,fork()后立即调用exec(),此时就无需复制了。fork()的实际开销就是复制父进程的页表以及给子进程创建唯一的进程描述符。在一般情况下,进程创建都会马上运行一个科执行的文件,这种优化可以避免拷贝大量根本不会被使用的数据。

2.fork()

    linux通过clone()系统调用实现fork()。这个调用通过一系列的参数标志来指明父、子进程需要共享的资源。fork()、vfork()和__clone()库函数都根据各自需要的参数标志去调用clone()。然后由clone()去调用do_fork()。

    do_fork完成了创建中的大部分工作,该函数调用copy_process()函数,然后让进程开始运行。copy_process()函数的工作:

  •     调用dup_task_struct()为新进程创建一个内核栈、thread_info结构和task_struct,这些值与当前进程的值相同。此时,子进程和父进程的描述符时完全相同的。
  • 检查新创建的这个子进程后,当前用户所拥有的进程数目没有超出给他分配的资源的限制。
  • 子进程着手是自己与父进程区别开来。进程描述符内的许多成员都要被清0或设为初始值。进程描述符的成员值并不是继承而来的,而主要是统计信息。进程描述度中的大多数数据都是共享的。
  • 接下来,子进程的状态被设置为TASK_UNINTERRUPTIBLE以保证它不会投入运行。
  • copy_process()调用copy_flags()以更新task_struct的flags成员。表明进程是否拥有禅机用户权限的PF_SUPERPRIV标志被清0。表明进程还没有调用exec()函数的PF_FORKNOEXEC标志被设置。
  • 调用get_pid()为新进程获取一个有效的PID
  • 根据传递给clone()的参数标志,copy_process()拷贝或共享打开的文件、文件系统信息、信号处理函数、进程地址空间和命名空间等。在一般情况下,这些资源会被给定进程的所有线程共享,否则,这些资源对每个进程是不同的,因此被拷贝到这里。
  • 让父进程和子进程平分剩余的时间片。
  • 最后,copy_process()作扫尾工作并返回一个指向子进程的指针。

3.vfork()

     vfork()系统调用和fork()的功能相同,除了不拷贝父进程的页表项。子进程作为父进程的一个单独的线程在它的地址空间里运行,父进程被阻塞,直到子进程退出或执行exec()。子进程不能向地址空间写入。在过去3BSD时期,这个优化是非常有意义的,那时并未使用写时拷贝复制页来实现fork()。现在由于执行fork()时引入了写时拷贝页并且明确了子进程先执行,vfork的好处就仅限于不拷贝父进程的页表项了。

vfork()系统调用的实现时通过向clone()的系统调用一个特殊标志来进行的。

  •     在调用copy_process()时,task_struct的vfork_done成员设置为NULL。
  • 在执行do_fork()时,如果给定特备标志,则vfork_done会指向一个特殊地址。
  • 子进程开始执行后,父进程不是马上恢复执行,而是一直等待,直到子进程通过vfork_done指针向它发送信号
  • 在调用mm_release()时,该函数用于进程退出内存地址空间,并且检查vfork_done是否为空,如果不为空,则会向父进程发送信号。
  • 回到do_fork(),父进程醒来并返回。

如果一切执行顺利,子进程在新的地址空间里运行,父进程也恢复了在原地址运行,但如果调用exec()失败呢?

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值