fork函数详解【Linux】

news2025/1/19 8:16:43

fork函数详解【Linux】

  • fork函数的概念
  • fork调用后的底层细节
  • 解释fork学习中的一些笔记和问题
  • fork的写实拷贝
    • 深拷贝的策略
  • fork调用失败的原因

fork函数的概念

  调用fork函数可以在已存在的进程中创建一个子进程,此时,新进程叫做子进程,原进程叫做父进程。

  #include <unistd.h>
  pid_t fork(void);
 其中pid_t的底层是int;
在这里插入图片描述
返回值::子进程中返回0,父进程返回子进程id,出错返回-1
也就是这样:

#include <iostream>
#include <unistd.h>
int main()
{
    pid_t fd = fork();
    if (fd == 0)
    {
        //this area is child

    }
    else if(fd > 0)
    {
        // this area is parent

    }
    else
    {
        // this area is error

    }

    return 0;
}

fork调用后的底层细节

  当我们在用户空间调用了fork以后,控制会从用户空间转移到内核空间,因为fork属于系统调用,然后内核会:

  1. 为子进程分配新的内存块和内核数据结构。
  2. 以父进程为模板,将父进程的pcb和虚拟内存地址以及页表汇中的内容完整复制一份给子进程,以至于虚拟内存地址和页表以及页表和物理地址空间的映射关系,父子进程此时都是一模一样的。
  3. 将子进程的pcb添加到系统进程列表中。
  4. fork返回,开始进程调度器调度。

解释fork学习中的一些笔记和问题

  1. 同一个程序,每次启动运行时,分配的pid都可能不同。
  2. 命令行中的父进程一般是命令行解释器bash,命令行中启动的进程,都是bash的子进程。
  3. Linux中创建子进程有两种方式:
    3.1. 在命令行行中直接启动进程。(启动进程的本质就是创建进程吗)
    3.2. 通过代码来创建子进程。(一般是由父进程创建)
  4. 只有父进程执行fork之前的代码,fork之后的代码父子进程都要执行。
  5. 创建子进程的原因:想让子进程协助父进程完成一些工作,这些工作是单进程完成不了的。(比如边下载边播放视频),创建子进程是为了和父进程做不一样的事。
  6. 为什么fork的两个返回值会给父进程返回子进程pid,给子进程返回0?
    :答:因为父子进程的数量比例是 1:n , 为了使得父子进程能够一一对应,具有唯一性,且子进程主要是为了协助父进程,父进程得到了子进程的pid能够确定唯一的子进程,方便调用子进程。
  7. fork之后,父子进程谁先运行?
    : 答:这个跟内核的调度机制有关,哪一个进程的pcb先被选择调度,哪一个进程就先执行,所以是不确定的。由各自pcb中的调度信息(时间片,优先级)和调度器算法决定,也就是有OS决定。

fork的写实拷贝

  由于虚拟内存地址和页表以及页表和物理地址空间的映射关系,父子进程此时都是一模一样的。所以可以说父子继承一开始都是使用同一块地址空间。

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
    int a = 8;
    pid_t fd = fork();
    if (fd == 0)
    {
        a = 3;
        std::cout << "child: " << a << std::endl;
    }
    if (fd > 0)
    {
        std::cout << "parent: " << a << std::endl;
    }

    wait(NULL);
    return 0;
}

在这里插入图片描述
  看完上面这份代码,为什么明明父子进程的a是同一块地址空间的,按理来说子进程修改了a为3,父进程的a为什么还是8呢?难道是结论错误了吗?

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
    int a = 8;
    std::cout << &a << std::endl;
    pid_t fd = fork();
    if (fd == 0)
    {
        a = 3;
        std::cout << "child: " << &a << std::endl;
    }
    if (fd > 0)
    {
        std::cout << "parent: " << &a << std::endl;
    }

    wait(NULL);
    return 0;
}

在这里插入图片描述
  通过上面这个代码也可以清楚知道父子进程的a指向的地址空间确实是同一个。

  这里的原因是因为我们所看到的地址叫做虚拟内存空间,每一个进程都会有一份虚拟内存和一个页表。但是物理内存只有一个,页表中保存着虚拟内存和物理内存之间的一份映射关系。

  我们可以浅显的将页表看做下图(真正页表中的字段不止三个,但是此刻这三个字段足以说明问题);
在这里插入图片描述
  所以真实情况是:子进程的创建确实以父进程为模板将其内容拷贝到了子进程的内核数据结构中,但是当数据有所变化时,就以深拷贝的方式父子进程各自私有一份。

深拷贝的策略

  1. 父进程创建子进程的时候会先将自己页表中的访问权限字段中的读写权限改为只读,然后再创建,使得父子进程的数据都是只读。
  2. 当父子进程任意一方试图更改共同数据,就会触发页表权限问题,在页表映射转换时出现权限问题会有两种情况:
    • 真的出错了
    • 不是出错,触发深拷贝的策略机制,需要进程重新申请内存
      此时显然是属于后者。
  3. 此时再物理内存中开辟了一段新空间,然后将更改后的数据写入到内存,页表中的物理地址也要改成新物理空间的地址。
  4. 因为没有更改虚拟地址,所以我们打印出来的地址会发现深拷贝之后的虚拟地址依旧没有改变。这也就解释了开头那份代码所带来的问题。

在这里插入图片描述

fork调用失败的原因

  • 系统中有太多的进程
  • 实际用户的进程数超过了限制

    😄 创作不易,你的点赞和关注都是对我莫大的鼓励,再次感谢您的观看😄

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

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

相关文章

100000000!文心一言披露最新用户规模

“文心一言用户规模突破1亿。” 12月28日&#xff0c;百度首席技术官、深度学习技术及应用国家工程研究中心主任王海峰在第十届WAVE SUMMIT深度学习开发者大会上宣布。会上&#xff0c;王海峰以《文心加飞桨&#xff0c;翩然赴星河》为题作了主旨演讲&#xff0c;分享了飞桨和文…

【tcp】TCP CLOSE_WAIT问题分析与定位

一、问题背景 某日&#xff0c;运维突然在群里突然丢出告警信息&#xff1a; 对象类型&#xff1a;主机 检测规则&#xff1a;NET.TCP.CLOSE.WAIT 告警内容&#xff1a;CLOSE_WAIT状态的TCP连接数大于500 ....image.png 上面告警信息已经说的很明白&#xff0c;CLOSE_WAIT状…

【UE在关卡序列制作图片序列,捕获影片时出现小白人下落的场景或者空场景】

UE在关卡序列制作图片序列,捕获影片时出现小白人下落的场景或者空场景 问题 下面是有问题的截图 1.如果场景没有放角色就是纯天空 2.如果有角色就是角色一直在下落 原因 使用影片场景捕获&#xff08;旧版时&#xff09;&#xff0c;如果镜头帧率的长度没有和影片的长度一致…

操作教程|MeterSphere UI测试+VNC:简单、快捷地查看UI测试实时执行详情

编者注&#xff1a;本文为CSDN博主hxe116的原创文章。 原文链接为&#xff1a;https://blog.csdn.net/hxe116/article/details/134714960?spm1001.2014.3001.5502 作为一款一站式的开源持续测试平台&#xff0c;MeterSphere涵盖了测试跟踪、接口测试、UI测试和性能测试等功能…

YOLO格式转VOC格式

#仅支持图片格式统一的,多格式图片需要完善 from xml.dom.minidom import Document import os import cv2 from PIL import Image import numpy as np def makexml

【MAX30102 T03】心率血氧传感器

目录 一、实物图 二、原理图 引脚定义 三、简介 选择模式 I2C 通讯格式&#xff1a; UART 通讯格式&#xff1a; 四、结构尺寸 五、注意&#xff1a; 作者&#xff1a;特纳斯电子 请以底部官方认证的推广方式联系作者 一、实物图 二、原理图 引脚定义 三、简介 血氧心率测量模…

Matplotlib的详细使用及原理

认识matplotlib Matplotlib是一个Python 2D绘图库&#xff0c;能够以多种硬拷贝格式和跨平台的交互式环境生成出版物质量的图形&#xff0c;用来绘制各种静态&#xff0c;动态&#xff0c;交互式的图表。 Matplotlib已经成为python中公认的数据可视化工具&#xff0c;我们所熟…

巨匠纺・品鉴窗帘是一线品牌吗,产品质量怎么样

巨匠纺・品鉴窗帘是一线品牌&#xff0c;产品品质有保障&#xff0c;作为深耕行业多年的窗帘品牌&#xff0c;巨匠纺・品鉴窗帘凭借不断升级的匠心品质、过硬的综合实力和品牌影响力在众多窗帘中脱颖而出&#xff0c;公司先后荣获中国 3.15 诚信品牌、中国绿色环保品牌、中国窗…

【学习笔记】GAN生成对抗神经网络原理与实践

最早在2014年Ian J. Goodfellow等人提出的GAN。 文献为&#xff1a;Generative Adversarial Nets GAN面临的主要挑战有模型训练困难&#xff0c;容易出现生成模型坍塌等问题。因为GAN是采用生成对抗策略来训练的&#xff0c;优化生成模型必然导致判别模型的损失增大。 定义 生…

旧衣回收小程序搭建,稳占回收市场

近几年我国大众的消费水平不断提升&#xff0c;闲置物品也相应增加了不少&#xff0c;尤其是闲置衣服&#xff0c;为了减少资源浪费&#xff0c;旧衣服回收回收行业受到了大众的关注。 目前我国旧衣服回收行业的市场规模达到了300多亿元&#xff0c;旧衣回收行业的商业价值非常…

机器学习之人工神经网络(Artificial Neural Networks,ANN)

人工神经网络(Artificial Neural Networks,ANN)是机器学习中的一种模型,灵感来源于人脑的神经网络结构。它由神经元(或称为节点)构成的层级结构组成,每个神经元接收输入并生成输出,这些输入和输出通过权重进行连接。 人工神经网络(ANN)是一种模仿生物神经系统构建的…

算法基础之整数划分

整数划分 核心思想&#xff1a; 计数类dp 背包做法 f[i][j] 表示 取 1 – i 的物品 总容量为j的选法数量 f[i][j] f[i-1][j] f[i-1][j-v[i]] f[i-1][j-2v[i]] f[i-1][j-3v[i]] ……f[i-1][j-kv[i]] f[i][j-v[i]] f[i-1][j-v[i]] f[i-1][j-2v[i]] f[i-1][j-3v[i]] ……f[i…

十分钟安装Tensorflow-gpu2.6.0+本机CUDA12 以及numpy+matplotlib各包版本协调问题

换了台机器&#xff0c;又装Tensorflow&#xff0c;记得我第一次装的时候装了好几天&#xff0c;而今天只用了十分钟就搞定了&#xff0c;因为这个方法只用在终端操作&#xff0c;不用去英伟达官网下载包&#xff0c;刷刷刷的贼快&#xff0c;只是后面去找版本的对应问题了又花…

模拟算法 蓝桥杯备赛系列 acwing

文章目录&#xff1a; 基础知识 什么是模拟&#xff1f; 例题 一、错误票据 1.解题思路 2.代码 二、移动距离 1.解题思路 2.代码 三、航班时间 1.解题思路 2.代码 四、外卖优先级 1.解题思路 2.代码 前面为了目录好看大家就当个玩笑看吧哈哈哈。下面上正文。 正文 基础知识 什…

码住!8个小众宝藏的开发者学习类网站

1、simplilearn simplilearn是全球排名第一的在线学习网站&#xff0c;它的课程由世界知名大学、顶级企业和领先的行业机构通过实时在线课程设计和提供&#xff0c;其中包括顶级行业从业者、广受欢迎的培训师和全球领导者。 2、VisuAlgo VisuAlgo是一个免费的在线学习算法和数…

Nginx直播服务器搭建及推拉流测试

文章目录 前言一、搭建 Nginx 直播服务器1、安装 Nginx 依赖2、下载并解压源码①、下载并解压 nginx-http-flv-module 直播模块源码②、下载并解压 Nginx 源码 3、编译安装4、配置 rtmp 服务①、添加 rtmp 服务②、验证配置 二、推流、拉流测试1、ffmepg 推流2、VLC 拉流 前言 …

【汇编笔记】初识汇编-内存读写

汇编语言的由来&#xff1a; CPU是计算机的核心&#xff0c;由于计算机只认识二进制&#xff0c;所以CPU执行的指令是二进制。 我们要想让CPU工作&#xff0c;就得给他提供它认识的指令&#xff0c;这一系列的指令的集合&#xff0c;称之为指令集。 指令集&#xff1a; 不同的体…

PyTorch深度学习实战(28)——对抗攻击(Adversarial Attack)

PyTorch深度学习实战&#xff08;28&#xff09;——对抗攻击 0. 前言1. 对抗攻击2. 对抗攻击模型分析3. 使用 PyTorch 实现对抗攻击小结系列链接 0. 前言 近年来&#xff0c;深度学习在图像分类、目标检测、图像分割等诸多领域取得了突破性进展&#xff0c;深度学习模型已经能…

React学习计划-React16--React基础(七)redux使用与介绍

笔记gitee地址 一、redux是什么 redux是一个专门用于做状态管理的js库&#xff08;不是react插件库&#xff09;它可以用在react、angular、vue的项目中&#xff0c;但基本与react配合使用作用&#xff1a;集中式管理react应用中多个组件共享的状态 二、什么情况下需要使用r…

go 源码解读 - sync.Mutex

sync.Mutex mutex简介mutex 方法源码标志位获取锁LocklockSlowUnlock怎么 调度 goroutineruntime 方法 mutex简介 mutex 是 一种实现互斥的同步原语。&#xff08;go-version 1.21&#xff09; &#xff08;还涉及到Go运行时的内部机制&#xff09;mutex 方法 Lock() 方法用于…