函数可以有两个返回值?初探神奇的fork()函数

一个函数的返回值可有两个

这里写图片描述

一个很简单的选择分支结构,学过基本语法的都知道,如果走if,就不会走else if. 当然,那是没有碰到fork()函数的时候.

为什么呢? 我们编译运行一下代码来观察结果.

这里写图片描述

发现两个printf都被执行了?难道if else 结构失效了? 其实不然

当程序运行起来就变成了进程

我们写的代码当没被运行的时候,只是躺在磁盘中冰冷冷的文本,当它被载入内存后,它变成进程后,生命周期才开始. 可执行程序载入内存的过程叫做”内存映射

Linux通过将一个虚拟内存区域与一个磁盘上的对象关联起来,以初始化这个虚拟内存区域的内容,这个过程成为内存映射.
–<<深入理解计算机系统>>

其实程序使用的是虚拟内存空间,有兴趣可以去我博客另一篇看一看
虚拟内存和缺页,为什么使用一键加速会使你的电脑变慢?

但这和一个函数有两个返回值有什么关系吗?

其实,并不是一个函数有两个返回值,而是调用fork函数后,在内存中一个进程被复制成两个进程, 分别被cpu执行. 那么执行出来肯定就会有两个结果.

简单点说就是一份文本,被分别两个人去解读,那么肯定就会有两个结果.

让父子进程各司其职

fork()函数是创建一个新进程, 它的返回值分别是

  • 子进程返回 0
  • 父进程返回子进程的进程号 (PID)

那么,我们就可以通过fork()函数的返回值识别父子进程,让其通过if else分流,干不同的事情

在代码中也有用到 getpid()和getppid(),其中

  • getpid()函数是返回该进程的的ID号 ID号的类型是 pid_t
  • getppid() 函数是返回该进程的父进程的ID号

遇到分歧如何处理

使用fork()函数,我们可以实现父子进程的各司其职,通常情况下井水不犯河水,

但是如果父子进程的任务重叠了,都想去改一数的值,那么情况是什么样的呢?

这里写图片描述

是儿子让老子 或者 老子让儿子呢?

这里写图片描述

显而易见,当出现数据改动时,父子进程还是是各自运行各自的.

其中在fork之后发生数据改动的情况,叫做”写时拷贝

在解释什么是写时拷贝 之前,我们有必要说说当函数调用fork()时会发生什么

怎么创建一个新进程

当一个程序进入内存后,操作系统去管理,调度它,那么肯定首先要获得这个进程的信息(PCB Process Control Block)

就好像学校在管理学生时,需要知道学生的姓名,年龄等信息

在Linux中,进程的信息被描述为一个叫task_struct 的结构体,操作系统通过对这个结构体的操控,间接操控进程.

调用程序fork()函数后,就把原来进程的 task_struct 直接又复制了一份,改一下里面的PID,就变成了一个新进程, 六耳猕猴.

因为进程是运行在虚拟内存中的,而且每个进程都有自己的虚拟内存空间

最后要映射到物理内存中,

物理内存是有限的,你不能复制一个进程,又映射到新的物理内存中去.国土宝贵,不会让你这么干.

解决的方法就是 写时拷贝:

你随便复制原有进程,随便开辟虚拟内存空间,

但是你只要是从我这复制的信息, 那么就必须映射到同一片物理内存上去,

并且咱两对这片物理空间都不能修改(标记为只读)

你想修改就重找一物理地址去保存你的值.

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值