创建新进程——fork函数

fork函数原型

#include<unistd.h>
pid_t fork(void);

关于fork的了解

一个现有的进程可以调用fork函数创建一个新的进程。由fork创建的新进程被称为子进程。


关于fork的返回值

fork函数被调用一次,但是它的返回值有两个。子进程的返回值为0,父进程的返回值则是新创建的子进程的ID。


fork函数创建子进程之后

父子进程继续执行fork调用之后的指令。子进程是父进程的副本。例如,子进程获得父进程的数据空间,堆和栈的副本。注意,这是子进程所拥有的副本。父进程和子进程并不共享这些存储空间的部分。父子进程共享的是正文段。


关于写时复制技术

fork函数创建出子进程以后,经常跟着exec,所以现在很多实现并不执行一个父进程数据段、栈和堆的完全副本。作为替代,使用了写时复制的技术。这些区域由父进程和子进程共享,而且内核将他们的访问权限改变成只读权限。如果父子进程中其中一个试图修改这些区域,则内核只为修改区域的这块内存制作一个副本,通常是虚拟存储系统中的一页。


子进程对变量所做的改变并不影响父进程中该变量的值



fork函数之后先执行父进程还是子进程

在fork函数之后先执行父进程还是子进程是不确定的,这是取决于内核所使用的调度算法。如果要求父进程和子进程之前相互同步,则要求某种形式的进程间通信。


文件共享

在重定向父进程的标准输出时,子进程的标准输出也被重定向。实际上,fork的一个特性是父进程的的所有打开文件描述符都被复制到子进程。我们说“复制”是因为对每个文件描述符来说,就好像执行了dup函数。重要的一点是,父进程和子进程共享同一个文件偏移量。如果父进程的标准输出已重定向,那么子进程写到标准输出时,它将更新与父进程共享的该文件的偏移量。


fork之后文件描述符有一下两种常见的情况

(1)父进程等待子进程完成。父进程无需对其描述符做任何处理

(2)父进程和子进程各自执行不同的程序段。父子进程各自关闭他们不需使用的文件描述符,不干扰对方使用的文件描述符。


fork失败的两个主要的原因

(1)系统中已经有了太多的进程

(2)该实际用户ID的进程总数超过了系统限制


fork的两种用法

(1)一个父进程希望复制自己,使父进程和子进程同时执行不同的代码段。这在网络服务进程中是常见的——父进程等待客户端的服务请求,子进程处理此请求。父进程继续等待下一个服务请求

(2)一个进程要执行一个不同的程序,子进程从fork返回后立即调用exec


fork和vfork的区别

(1)fork和vfork一样都是创建一个子进程,但是它并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec(或exit),于是也就不会引用该地址空间,不过在子进程调用exec(或exit)之前,他在父进程的空间中运行。

(2)vfork保证子进程先运行,在它调用exec(或exit)之后,父进程才可能被调度运行,当子进程调用这两个函数(exec或exit)中的任意一个时,父进程会恢复运行。(如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁)。因为我们可以保证在子进程调用exec或exit之前,内核会使父进程处于休眠状态。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值