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

news2024/12/29 10:47:05

文章目录

  • 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.coloradmin.cn/o/1535773.html

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

相关文章

网络编程:学生管理系统

一、实现功能 1.添加学生信息 2.删除学生信息 3.修改学生信息 4.查找学生信息 二、添加 int do_add(sqlite3 *ppDb) {// 准备sql语句int add_num 0;char add_name[20] "";double add_score 0;// 提示并输入数据printf("请输入学号:");scanf("%d&q…

芯片公司SAP管理架构:科技与管理的完美融合

在当今日新月异的科技时代&#xff0c;芯片公司作为信息技术领域的核心力量&#xff0c;其运营管理的复杂性日益凸显。SAP管理架构作为一种高效的企业资源规划系统&#xff0c;为芯片公司提供了强大的管理支持。本文将为您科普芯片公司SAP管理架构的相关知识。 SAP管理架构是一…

使用倒模耳机壳UV树脂胶液制作舞台监听耳返入耳式耳机壳有哪些优点?

使用倒模耳机壳UV树脂胶液制作舞台监听耳返入耳式耳机壳有很多优点&#xff0c;具体如下&#xff1a; 高音质表现&#xff1a;通过倒模工艺制作的耳机壳能够更好地贴合耳朵&#xff0c;减少声音散射和反射&#xff0c;提高声音的清晰度和质感。这对于舞台监听来说非常重要&…

USB调试工具大全-USB中文网

USB中文网在此之前开发了很多的应用层USB设备调试工具&#xff0c;再加上收集的一些其它相关工具&#xff0c;并将这些调试工具分享给各位USB开发者爱好者&#xff0c;帮助大家更快的学习和了解USB相关的知识。 不过酒香也怕巷子深&#xff0c;今天我们就将这些调试工具的导航…

带你学会深度学习之卷积神经网络[CNN] - 5

前言 本文不讲述如泛化&#xff0c;前向后向传播&#xff0c;过拟合等基础概念。 本文图片来源于网络&#xff0c;图片所有者可以随时联系笔者删除。 本文提供代码不代表该神经网络的全部实现&#xff0c;只是为了方便展示此模型的关键结构。 CNN&#xff0c;常用于计算机视…

Leetcode 200. 岛屿数量

心路历程&#xff1a; 在没有看图论这一章之前看这道题没什么直接的思路&#xff0c;在看完图论之后&#xff0c;学着使用DFS和BFS去套用解决。第一次自己做的时候还是遇到了很多小问题。整体思路很流畅&#xff0c;但是需要处理的细节第一次没怎么处理好&#xff0c;花了很多…

如何使用Android平板公网访问本地Linux code-server

文章目录 1.ubuntu本地安装code-server2. 安装cpolar内网穿透3. 创建隧道映射本地端口4. 安卓平板测试访问5.固定域名公网地址6.结语 1.ubuntu本地安装code-server 准备一台虚拟机,Ubuntu或者centos都可以&#xff0c;这里以VMwhere ubuntu系统为例 下载code server服务,浏览器…

OR-806A固态继电器光耦

固态继电器 VL60V输出端击穿电压光耦 高隔离电压 60 至 600V 输出耐受电压 工业温度范围&#xff1a;-40 to 85℃ 高灵敏度和高速响应、 特征 输入和输出之间的高隔离电压 &#xff08;Viso&#xff1a;5000 V rms&#xff09;。 控制低电平模拟信号 高灵敏度和高速响应…

含“AI”量上涨,智能模组SC208系列助力智慧零售全场景高质发展

AI正重塑智慧零售产业&#xff0c;加速零售在采购、生产、供应链、销售、服务等方面改善运营效率和用户体验。零售行业经历了从线下到线上再到全渠道融合发展过程&#xff0c;“提质、降本、增效、高体验”是亘古不变的商业化与智能化方向。含“AI”量逐渐上涨的智慧零售正经历…

Linux:Gitlab:16.9.2 (rpm包) 部署及基础操作(1)

1.基础环境 我只准备了一台gitlab服务器&#xff0c;访问就用真机进行访问&#xff0c;接下来介绍一下详细配置 centos7 内网ip:192.168.6.7 外网ip:172.20.10.4 运行内存&#xff1a;4G CPU:4核 先去配置基础环境 关闭防火墙以及selinux 再去下载基础的运行…

差分逻辑电平 --- SSTL、HSTL、HSUL结构

SSTL/HSTL/HSUL 属于DDR存储器接口逻辑电平&#xff0c;虽然是单端&#xff0c;本质上是差分对&#xff0c;因实现机制是将信号与参考电平Vref组成差分对进行比较。 SSTL SSTL&#xff1a;Stub Series Termination Logic&#xff0c;短截线串联端接逻辑。 我们所熟知的DDR 采…

记录西门子200:PUT和GET通讯测试

GET/PUT&#xff1a;S7-200SMART之间专有通讯协议。 准备两台Smart-PLC&#xff0c;这里使用的ST60和CR40。外加一个交换机。 CR40的地址设置是&#xff1a;192.168.2.1 用来读 ST60的地址设置是&#xff1a;192.168.2.2 用来写 打开软件&#xff0c;选择CPU-CR4配…

LeetCode_Java_递归系列(题目+思路+代码)

206.反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]以此类推&#xff0c;直到反转结束返回头结点 class Solution {public ListNode rever…

统计-R(相关系数)与R^2(决定系数)

1.相关系数&#xff08;R&#xff09; 定义&#xff1a;考察两个事物&#xff08;在数据里我们称之为变量&#xff09;之间的相关程度。 假设有两个变量X&#xff0c;Y&#xff0c;那么两个变量间的皮尔逊相关系数可通过以下公式计算&#xff1a; 公式一&#xff1a; 其中…

创建一个electron-vite项目

前置条件&#xff1a;非常重要&#xff01;&#xff01;&#xff01; npm: npm create quick-start/electronlatest yarn: yarn create quick-start/electron 然后进入目录&#xff0c;下载包文件&#xff0c;运行项目 到以上步骤&#xff0c;你已经成功运行起来一个 electr…

【C++】vector容器初步模拟

送给大家一句话&#xff1a; 努力一点&#xff0c;漂亮—点&#xff0c;阳光一点。早晚有一天&#xff0c;你会惊艳了时光&#xff0c;既无人能替&#xff0c;又光芒万丈。 vector容器初步模拟 1 认识vector开始了解底层实现 2 开始实现成员变量构造函数 析构函数尾插迭代器插入…

新零售SaaS架构:线上商城系统架构设计

零售商家为什么要建设线上商城&#xff1f; 传统的实体门店服务范围有限&#xff0c;只能吸引周边500米以内的消费者。因此&#xff0c;如何拓展服务范围&#xff0c;吸引更多的消费者到店&#xff0c;成为了店家迫切需要解决的问题。 缺乏忠实顾客&#xff0c;客户基础不稳&…

分治法排序:原理与C语言实现

分治法排序&#xff1a;原理与C语言实现 一、分治法与归并排序概述二、归并排序的C语言实现三、归并排序的性能分析四、归并排序的优化 在计算机科学中&#xff0c;分治法是一种解决问题的策略&#xff0c;它将一个难以直接解决的大问题&#xff0c;分割成一些规模较小的相同问…

数据可视化实战(三)

图书销量情况对比 import pandas as pd import matplotlib.pyplot as plt # 读取Excel数据 dfpd.read_excel(mrbook.xlsx) df序号书号序号.1月份销量rate0B189.787569e1211月15060.31B199.787569e1222月1200-0.32B259.787569e1233月33050.63B219.787569e1244月66100.54NaNNaN5…

docker 进入容器内部命令

docker容器运行了&#xff0c;怎么进入容器内部查看内部的文件情况呢&#xff1f; 答&#xff1a;可以通过docker exec 的命令查看。 docker exec --help 可以查看命令介绍 &#xff1a; docker exec -it XXX /bin/bash XX为容器ID 进入容器内部 /bin/bash是需要添加的 不…