【创建进程】fork函数与写时拷贝

文章目录

  • fork函数
    • fork如何返回两个值(fork的工作原理)
    • 如何解释父子进程相互输出printf
  • 写时拷贝

fork函数

#include <unistd.h>
pid_t fork(void);
返回值:自进程中返回0,父进程返回子进程id,出错返回-1

fork函数是一个Unix/Linux系统中常用的系统调用,用于创建一个新的进程新进程称为子进程原进程称为父进程。fork函数的工作原理是将父进程的内存空间完全复制一份给子进程,包括代码段、数据段、堆栈等,但是子进程会有自己独立的进程ID(PID)
fork函数会 返回两次 ,在父进程中返回子进程的PID,在子进程中返回0如果创建失败则返回一个-1返回值的类型为pid_t,实质是int.

一个函数调用一次但是可以返回两次值,这是令人感到奇怪的,我们可以通过代码来观察该现象

观察以下代码:
在这里插入图片描述

我们可以发现,fork函数确实返回了两个值,对于父进程而言,拿到的的就是子进程的pid.对于新建立出来的子进程来说,fork返回值就是0.(27502是bash进程)

对于该相象,我们提出疑问:

fork如何返回两个值(fork的工作原理)

我们将代码以fork函数为界限,划分为上下两个部分,before和after。创建子进程后子进程会向下开始执行after代码,并不会执行before。在fork内部,执行了一部分代码的时候,子进程已经被建立。几乎是瞬间,子进程被调度,父子进程并发往后执行代码,所以return会执行两次

在这里插入图片描述
在这里插入图片描述

当代码执行到fork函数时,由于fork函数是一个系统调用,这个时候需要由linux内核来创建一个子进程,子进程获得与父进程用户级虚拟地址空间相同的(但是独立的)一份副本,包括父进程的栈、数据段、堆和代码,并申请一个PCB
完成这个工作后,子进程也就有了自己的一个PID,fork函数就会将这个PID立即返回给父进程。因为子进程的PID总是非0的,返回值就提供一个明确的方法来分辨程序是在父进程还是在在子进程中执行。所以给子进程返回一个0.

注意,父进程和子进程是并发运行的独立进程,执行的先后顺序由系统的调度算法决定。虽然上述例子是先执行父进程的printf,但是在其它系统上可能不一样
在这里插入图片描述

如何解释父子进程相互输出printf

用fork创建出来的子进程与父进程共享文件。我们注意到以上例子中,父进程和子进程程都把他们的输出显示在屏幕文件中。原因是子进程继承了父进程的所有的打开文件。当父进程调用fork时,stdout(标准输出流)文件是打开的,并指向屏幕。子进程继承了这个文件,因此它的输出也是指向屏幕的

我们可以画进程图来帮助我们理解
在这里插入图片描述

观察现象2:
观察以下代码
在这里插入图片描述
在这里插入图片描述

通过以上例子我们可以得到结论:
1.父子进程的具有相同但是独立的地址空间。在创建子进程时,本地变量val在父进程中和在子进程中都是0。后面因为父进程和子进程是独立的进程,它们都有自己私有的地址空间。无论是父进程还是子进程对val的任何改变都是独立的,不会放映到另一个进程的内存中。这也可以解释为什么父进程和子进程调用它们各自的printf语句时,他们的变量val会有不同的值。

2.虽然父子进程的变量的虚拟地址相同,但是映射的物理地址不同。这也是为什么父子进程的val地址相同,值却不同。发生了写时拷贝。

写时拷贝

写时拷贝,又叫写时复制(Copy-on-write,简称COW)。是一种计算机程序设计领域的优化策略。其核心思想是,如果多个调用者同时请求同一个资源,比如内存中的存储数据,它们会获得相同的指针来指向相同的资源。如果有一个进程想要修改其内容,为了避免影响其它进程,系统这个时候才会真正的复制一份相同的资源给该进程。其它进程所指向的该资源依旧保持不变。这种机制一定程度上减少了系统拷贝资源的次数。只要进程没有修改该资源,就不会有副本被创建,因此多个调用者只是读取操作时可以共享同一份资源

再次回到第二个例子中:
当使用fork创建子进程的时候,子进程获得父进程的一份用户级的虚拟地址空间相同的一份副本。根据写时拷贝的机制,此时系统并不会马上给子进程深拷贝父进程的资源,而是先给子进程共享同一片地址空间,并将该页面标记为只读。一旦父进程或者是子进程对该空间进行写入操作,系统才会真正的拷贝一份副本。

在这里插入图片描述

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

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

相关文章

Linux - 应用层HTTPS、传输层TCP/IP模型中典型协议解析

目录 应用层&#xff1a;自定制协议实例 HTTP协议首行头部空行正文http服务器的搭建 HTTPS协议 传输层UDP协议TCP协议 应用层&#xff1a; 应用层负责应用程序之间的沟通—程序员自己定义数据的组织格式 应用层协议&#xff1a;如何将多个数据对象组织成为一个二进制数据串进行…

ES集群部署指引

文章目录 引言I 清除last_run_metadata_path数据。II 配置IP2.1 CentOS系统的IP参数2.2 shell脚本-静态网络配置III 公司工作电脑的IP多号段配置3.1 Mac电脑3.2 windows系统see alsomac Rootlees 内核保护措施引言 申请两台Linux机器,存储1年的航迹数据,需要4T的存储空间。 E…

在Linux 中,如何配置网桥?如何配置虚拟网络

在Linux中配置网桥和虚拟网络主要涉及到编辑网络配置文件以及使用特定的命令。以下是一些详细的步骤讲解&#xff1a; 一、配置网桥 编辑网络配置文件 打开终端&#xff0c;使用文本编辑器&#xff08;如vi或nano&#xff09;编辑网络配置文件。对于eth0网络接口&#xff0c…

鸿蒙ArkTS语言快速入门-TS(五)

相关文章快速入口&#xff1a;鸿蒙ArkTS语言快速入门-TS&#xff08;四&#xff09; TS入门学习第五篇 TS入门学习第五篇模块导出模块 exports导入模块 imports 外部模块命名空间 TS入门学习第五篇 模块 模块在其自身的作用域里执行&#xff0c;而不是在全局作用域里&#x…

【算法刷题 | 二叉树 03】3.22 二叉树的层序遍历02(5题:在每个树行中找最大值,填充每个节点的下一个右侧节点指针,二叉树的最大深度,最小深度)

文章目录 5.6 515_在每个树行中找最大值5.6.1问题5.6.2解法&#xff1a;层序遍历 5.7 116_填充每个节点的下一个右侧节点指针5.7.1问题5.7.2解法&#xff1a;层序遍历 5.8 116_填充每个节点的下一个右侧节点指针||5.8.1问题5.8.2解法&#xff1a;层序遍历 5.9 104_二叉树的最大…

postgres数据库中的几种常用的几何空间运算

1、线/面几何数据生成点数据 select st_pointonsurface(geom) from table#根据面或者线生成中心点 2、使用row_to_json()方法可以构建json对象 3、根据面集合数据生成轮廓边界面数据 SELECT ST_ExteriorRing((ST_Dump(geom)).geom) FROM my_table 4、判断点是否在自定义的面…

Transformer的前世今生 day02(神经网络语言模型、词向量)

神经网络语言模型 使用神经网络的方法&#xff0c;去完成语言模型的两个问题&#xff0c;下图为两层感知机的神经网络语言模型&#xff1a; 假设词典V内有五个词&#xff1a;“判断”、“这个”、“词”、“的”、“词性”&#xff0c;且要输出P(w_next | “判断”、“这个”、…

揭秘最热门AI写作软件,看看有哪些值得推荐的AI写作神器

在快节奏的现代生活中&#xff0c;我们常常面临各种压力&#xff0c;例如工作、学习等。因此&#xff0c;一款能够提高写作效率的工具变得尤为重要。那么&#xff0c;有没有什么AI写作软件是比较好用的呢&#xff1f;下面小编给大家推荐几款热门的写作软件。 一.爱制作AI写作 …

什么是分布式

一个系统 各组件分别部署在不同服务器。彼此通过网络通信和协调的系统。 可以指多个不同组件分布在网络上互相协作&#xff0c;比如说电商网站也可以一个组件的多个副本组成集群&#xff0c;互相协作如同一个组件&#xff0c;比如数据存储服务中为了数据不丢失而采取的多个服务…

AI时代,Matter如何融入与服务中国智能家居市场,助力中国企业出海?

随着智能家居产业的飞速发展&#xff0c;丰富多样的智能家居产品为消费者带来了便利的同时&#xff0c;因为不同品牌、不同产品之间的协议与标准不统一&#xff0c;导致消费者体验产生割裂&#xff0c;本来想买个“智能”家居&#xff0c;结果买了个“智障”家居&#xff0c;这…

大模型时代如何做安全?

现在应该没人怀疑AI时代的到来了吧&#xff0c;在HUB上每天100的新的预训练模型产生&#xff0c;不夸张的说的&#xff0c;现在稍微有点计算机基础的人都可以训练自己的模型了。 说远了&#xff0c;还是说说那些不争气的安全厂商吧。为啥只说安全厂商&#xff1f;因为国内还是…

SQL日期函数

文章目录 1.获取日期时间函数1.1 获取当前日期时间1.2 获取当前日期1.3 获取当前时间 2.日期格式化★★★2.1 日期转指定格式字符串2.2 字符串转日期 3.日期间隔3.1 增加日期间隔 ★★★3.2 减去一个时间间隔★★★3.3 日期相差天数&#xff08;天&#xff09;3.4 相差时间&…

QT中如何设置当前界面的背景图片并随着窗口拉伸而刷新

1、为当前主窗口设置背景图片 QSize size this->size();int width size.width();int height size.height();QPixmap pixmap("../src/B002.png"); //通过构造函数载入图片方式label1 new QLabel(this);label1->resize(width,height);pixmap.scaled(lab…

腾讯二面:如何保证接口幂等性?高并发下的接口幂等性如何实现?

什么是接口幂等性 接口幂等性这一概念源于数学&#xff0c;原意是指一个操作如果连续执行多次所产生的结果与仅执行一次的效果相同&#xff0c;那么我们就称这个操作是幂等的。在互联网领域&#xff0c;特别是在Web服务、API设计和分布式系统中&#xff0c;接口幂等性具有非常…

嵌入式软件面试-linux-中高级问题

Linux系统启动过程&#xff1a; BIOS自检并加载引导程序。引导程序&#xff08;如GRUB&#xff09;加载Linux内核到内存。内核初始化硬件&#xff0c;加载驱动&#xff0c;建立内存管理。加载init进程&#xff08;PID为1&#xff09;&#xff0c;通常是systemd或SysVinit。init…

安卓使用MQTT实现阿里云物联网云台订阅和发布主题(3)

一、订阅主题代码讲解 private final String mqtt_sub_topic "/sys/k0wih08FdYq/LHAPP/thing/service/property/set";//订阅话题//mqtt客户端订阅主题//QoS0时&#xff0c;报文最多发送一次&#xff0c;有可能丢失//QoS1时&#xff0c;报文至少发送一次&#xff0c…

23 OpenCV 直方图比较

文章目录 直方图比较的目的相关性计算 (CV_COMP_CORREL)卡方计算 (CV_COMP_CHISQR)十字计算(CV_COMP_INTERSECT)巴氏距离计算 (CV_COMP_BHATTACHARYYA )compareHist 直方图比较算子示例 直方图比较的目的 直方图比较的目的是衡量两幅图像之间的相似度或差异度。通过计算图像的颜…

linux下用docker部署es和kibana(带ik分词器)(二)

在上一篇文章中讲到&#xff0c;我们利用docker安装了es和kibana&#xff0c;下面我们讲解一下在安装es时把ik分词器这个插件集成进去&#xff0c;首先我们编写一个dockerfile文件&#xff0c;自定义一个es镜像&#xff0c;当然这个镜像肯定集成了ik分词器&#xff0c;具体步骤…

【LVGL-开关部件】

LVGL-开关部件 ■ LVGL-开关部件■ 开关部件&#xff1a;指示器打开的颜色■ 开关部件&#xff1a;不可修改■ 开关部件&#xff1a;获取开关状态■ 开关部件&#xff1a;示例一&#xff1a;制冷,制暖,开关 ■ LVGL-开关部件 ■ 开关部件&#xff1a;指示器打开的颜色 ■ 开关部…

探讨Java代码混淆加固工具

摘要 本篇博客将介绍几种常用的Java代码混淆工具&#xff0c;如ProGuard、Allatori Java Obfuscator、VirboxProtector、ipaguard和DashO。我们将深入探讨它们的特点、功能以及在保护Java应用程序安全方面的作用。此外&#xff0c;还将强调在使用Java代码混淆工具时需要注意的…