Linux 复制进程fork

news2025/1/10 16:11:25

一、父进程和子进程

当前的一个进程在fork的时候可以复制当前的进程产生一个进程,这时产生出来的这个进程就是子进程,被复制的进程叫做父进程。子进程会将环境变量从父进程继承过来,或者说被拷贝过来。父进程也会有它的父进程,一层一层往上走,最顶头的父进程是读取了一些文件才得到了这些环境变量的值,这样的话一个进程就有了,这个进程有了之后,就会把这些环境变量的值传给它后边的进程,它后边的进程一直往后传。

在运行一个程序的时候,这个程序处在内存中,给这个程序分配内存空间,fork产生的子进程也要给它分配内存空间,原来的父进程需要多少内存空间,复制出来的子进程就需要多少内存空间,系统原来描述父进程有一个PCB,现在产生的子进程也需要有一个PCB,也就是所有父进程的资源都要拷贝一份给子进程,父进程和子进程一模一样,两个进程一起执行。但是子进程不是从头开始执行,是从fork复制的位置开始执行。

二、 fork 方法

语法形式:

pid_t  fork(void)

函数返回类型pid_t实质是int类型。这个pid_t实际上就是进程的一个id号,所以它实际上就是一个整型值。

这个返回值比较复杂,因为fork之后会变成两个进程,一个父进程,一个子进程,fork 函数新生成的一个进程就是子进程。调用fork函数的进程为父进程,新生成的进程为子进程。 这个fork会在父进程中返回一个值,这个值是子进程的pid,即子进程的id号;在子进程中也返回一个值,子进程中返回的是0,如果失败则返回-1。也就是说,在父进程中返回子进程的pid,在子进程中返回0,失败返回-1。

fork执行之后会有父进程和子进程两个进程,两个进程都执行同一套代码,区分到底是父进程在执行,还是子进程在执行,就看fork的返回值。父进程中fork的返回值是大于0的,子进程中fork的返回值等于0。

1.当前进程复制产生一个子进程的过程

代码如下图所示:

在这里插入图片描述

以返回值作为判断是父进程在执行还是子进程在执行的条件,然后循环输出父进程和子进程的执行结果。

编译并执行以上代码:

在这里插入图片描述

从结果可以看出子进程和父进程两个进程并发运行,无论是先执行父进程还是先执行子进程都是可以的。

2.当前进程复制产生一个子进程之后子进程和父进程当前的pid是怎样的?

在这里插入图片描述

通过getpid()得到当前进程的pid。

编译并运行以上代码:

在这里插入图片描述

根据运行结果可以看出子进程比父进程的pid大,这是因为子进程是父进程复制而来的,子进程肯定比父进程晚一些。

当前进程复制产生一个子进程的过程分析:

当程序执行到fork之后,就把当前的进程复制了一份,产生子进程,即子进程和父进程,两个进程分别执行,两个进程具有相同的代码,假设如上述代码当前父进程的pid为264088,新产生出来的子进程的pid为264089。

当fork执行完毕之后,接下来就从fork返回的地方开始继续执行,在当前父进程中fork的返回值就是子进程的pid,即264089,这时pid的值既不等于-1也不等于0,所以就是父进程在执行,跳转到代码中的

n=7;
s="parent";

这一部分,然后再去循环输出结果,输出的时候获取的pid是当前进程的pid,也就是父进程的pid,即264088。这时输出的s就是"parent"。

接下来到了子进程,子进程并不是从头开始执行,而是也从fork返回值得地方开始执行,子进程中fork的返回值是固定值0,所以这时子进程在执行,跳转到代码中的

n=3;
s="child";

这一部分,然后再去循环输出结果,输出的时候获取的pid是当前进程的pid,也就是子进程的pid,即264089。这时输出的s就是"child"。

仅仅由于fork的返回值不同,代码执行的分支不一样。

fork产生一个子进程之后fork就结束了,产生的子进程也不会无限fork下去,因为子进程是从fork带回返回值的位置开始执行。fork不会多次执行。同样在父进程中也不会多次执行fork,也是从fork返回值位置开始执行。

3.父进程和子进程的内存空间

代码如下图所示:

在这里插入图片描述

编译并运行的结果如下:

在这里插入图片描述
运行结果:n=3和n=7时,n的值不同,但是地址的值却是一样的。

分析:在物理内存中父进程和子进程用的不是同一块内存空间而是分开的,父进程用的是父进程的内存空间,子进程用的是子进程的内存空间。之所以运行结果中的地址是相同的,是因为那是逻辑地址,逻辑地址也就是距离起始位置的偏移量,逻辑地址相同是因为举例起始位置的偏移量相同,所以父进程和子进程的逻辑地址是相同的。打印的地址一般都是逻辑地址,而不是物理地址,物理地址一般看不到,物理地址要经过页表进行转换才能看到物理地址。正常情况下,程序中无法直接打印物理地址。

因此,父进程和子进程的逻辑地址是相同的,但是物理地址不相同。子进程的相对地址还是和父进程中一样的。

三、写时拷贝

假如父进程和子进程两个进程的内容暂时是一样的,现在只修改父进程中其中两个物理内存的值,其它物理内存不做任何修改,那么就把父进程中这两个物理内存的值各复制了一份给了子进程,子进程重新分配两个物理内存用来存放对应的值,接下来对于父进程中不做修改的物理内存,子进程中就不分配物理内存来存放这块物理内存中的值了,而是让子进程直接去使用父进程中没有被修改物理内存中的值,也就是没有被修改的物理内存就不会被复制一份给子进程,而是让父进程和子进程共享同一个物理内存。等到父进程或者子进程要修改被共享的物理内存时,父子进程就不能共享了,因为修改了之后,父进程和子进程对应的物理内存就不一样了,这时就只能把父进程被修改的物理内存的值复制一份给子进程,子进程重新分配物理内存来存放对应的值。

这个共享的过程就是写时拷贝,写时拷贝的目的是为了提高fork复制的性能。在写时拷贝的时候,系统记录这个内存正在被两个进程所引用,一旦其中一个进程结束之后,这块物理内存空间不会被释放掉。

写时拷贝对于用户来说时透明的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/876475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【动态规划基础】数字三角形(IOI1994)

题目描述 数字三角形 输入输出样例 输入样例#1: 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5输出样例#1: 30思路: 这题可能看到的第一眼——直接贪心然后一层一层判断呀!!!不过很快又会发现,额___好…

小白如何轻松制作产品帮助中心页面?

产品帮助中心是每个网站/产品必不可少的页面,产品帮助中心页面成为了企业提供客户支持和解决方案的重要组成部分。对于初次接触建立帮助中心页面的小白来说,也许会感到一些困惑和无从下手。本文将为小白介绍如何轻松制作产品帮助中心页面,帮助…

16 dplsys GAN

和有监督的分类工作不同,生成任务的目标更不明确。难以评价生成结果的好坏。 Oracle discriminator 假设我们有一个先知判别器oracle discriminator可以分辨我们生成的内容是真还是假。 我们想让生产成的结果足够真实,所以要 fool Oracle discriminato…

将el-table中的展开列(expand)修改成slots自定义插槽

用过element-ui的有知道,展开这个箭头无法自定义,一点办法都没有,官方根本就没提供预留任何位置给你操作。 从下面图中,可以看到有两个插槽,默认插槽和表头插槽。 我们来扩展一个自定义插槽来实现我们想要的功能。…

【dubbo】自定义filter打印接口请求日志

目标 在应用调用dubbo接口或提供的dubbo接口被调用时,通过自定义的filter打印接口请求时的入参信息、服务名、方法名及返回值 实现filter 1. 自定义filter实现类 Slf4j Activate(group {"provider", "consumer"}) public class DubboProvi…

展会动态 | 迪捷软件邀您参加2023ATC汽车电子软件与软件技术周

论坛背景 随着汽车智能化和电动化的发展,汽车电子与软件技术已经成为汽车产业的重点方向。为促进行业创新发展,各大汽车厂商、供应链企业和研究机构都在积极探索新的技术和应用。 2023ATC汽车电子与软件技术周(以下简称“技术周”&#xff…

pytest的fixture梳理

fixture特性 可以重复使用,多个用例可以使用同一个fixture一个测试用例可以使用多个装置 import pytest # Arrange pytest.fixture def first_entry():return "a"# Arrange pytest.fixture def second_entry():return 2# Arrange pytest.fixture def or…

Linux常用命令——dmidecode命令

在线Linux命令查询工具 dmidecode 在Linux系统下获取有关硬件方面的信息 补充说明 dmidecode命令可以让你在Linux系统下获取有关硬件方面的信息。dmidecode的作用是将DMI数据库中的信息解码,以可读的文本方式显示。由于DMI信息可以人为修改,因此里面…

【数据结构与算法】二叉搜索树

文章目录 二叉搜索树的结构二叉搜索树的实现节点的定义二叉搜索树的框架构造函数拷贝构造函数赋值运算符重载析构函数搜索操作插入操作删除操作 二叉搜索树的应用二叉搜索树的效率 二叉搜索树的结构 在浅学一下二叉树链式存储结构的遍历_链式存储二叉树按层次遍历_LeePlace的博…

【SpringBoot】| 接口架构风格—RESTful

目录 一:接口架构风格—RESTful 1. 认识RESTful 2. RESTful 的注解 一:接口架构风格—RESTful 1. 认识RESTful (1)接口 ①接口: API(Application Programming Interface,应用程序接口&…

NLP文本匹配任务Text Matching [有监督训练]:PointWise(单塔)、DSSM(双塔)、Sentence BERT(双塔)项目实践

NLP文本匹配任务Text Matching [有监督训练]:PointWise(单塔)、DSSM(双塔)、Sentence BERT(双塔)项目实践 0 背景介绍以及相关概念 本项目对3种常用的文本匹配的方法进行实现:Poin…

物联网和不断发展的ITSM

物联网将改变社会,整个技术行业关于对机器连接都通过嵌入式传感器、软件和收集和交换数据的电子设备每天都在更新中。Gartner 预测,全球将有4亿台互联设备投入使用。 无论企业采用物联网的速度如何,连接设备都将成为新常态,IT服务…

iVX引领自动编程新时代:从百万应用到普适AST转换的技术突破

一、引言 在人工智能和自动编程的交汇点上,iVX以其独特的自动编程训练模型,正引领着新一轮的技术革命。通过百万个通过iVX IDE生成的应用进行有监督训练,iVX成功地将任意网站或网页转成了iVX IDE中的AST,展示了其强大的技术实力。…

浅谈GIS和三维GIS的区别?

GIS(地理信息系统)和三维GIS(3D地理信息系统)是地理信息领域的两个重要概念,它们在地理数据的处理和分析方面具有不同的特点和应用。可能很多人分不清二者的区别,本文就带大家简单了解一下二者的区别。 定义…

【闲侃历史】 唐朝----安史之乱那些事(1)

说到安史之乱,可谓是唐朝最乱的一段时期,据说唐朝当时也就5000多万人,而经历了这一战,人口只剩1000多万人了。著名的杨国忠和杨贵妃也是在这个时候死的。这个系列我们就先来侃侃发起安史之乱的两个人----安禄山和史思明 一. 安禄…

免费插件集-illustrator插件-Ai插件-路径编辑-统一线宽

文章目录 1.介绍2.安装3.通过窗口>扩展>知了插件4.功能解释5.示例6.总结 1.介绍 本文介绍一款免费插件,加强illustrator使用人员工作效率,统一路径线宽。首先从下载网址下载这款插件 https://download.csdn.net/download/m0_67316550/87890501&am…

2023年05月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:输出第二个整数 输入三个整数,把第二个输入的整数输出。 时间限制:1000 内存限制:65536 输入 只有一行,共三个整数,整数之间由一个空格分隔。整数是32位有符号整数。 输出 只有一行,一个整…

支持M1 Syncovery for mac 文件备份同步工具

Syncovery for Mac 是一款功能强大、易于使用的文件备份和同步软件,适用于需要备份和同步数据的个人用户和企业用户。Syncovery 提供了一个直观的用户界面,使用户可以轻松设置备份和同步任务。用户可以选择备份的文件类型、备份目录、备份频率等&#xf…

【python实现向日葵控制软件功能】手机远程控制电脑

大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页: lqj_本人_python人工智能视觉(opencv)从入门到实战,前端,微信小程序-CSDN博客 最新的uniapp毕业设计专栏也放在下方了: https://blog.csdn.net/lbcy…

Redis数据结构——Redis简单动态字符串SDS

定义 众所周知,Redis是由C语言写的。 对于字符串类型的数据存储,Redis并没有直接使用C语言中的字符串。 而是自己构建了一个结构体,叫做“简单动态字符串”,简称SDS,比C语言中的字符串更加灵活。 SDS的结构体是这样的…