Fork() 函数:“父” 与 “子” 进程的交互(进程的创建)

阅读导航
- 前言
- 一、fork函数初识
- 1. 基本概念
- 2. fork函数返回值
- 二、fork函数的写时拷贝
- 三、总结
- 温馨提示
前言
前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的一些知识,也学习了一些Linux的基本操作,也了解并学习了有关Linux开发工具vim 、gcc/g++ 使用、yum工具以及git 命令行提交代码也相信大家都掌握的不错,上一篇文章我们了解了关于进程的基本概念,今天博主带大家了解一下编程中的一个非常重要的函数 —— fork(), 下面话不多说坐稳扶好咱们要开车了!!!😍
一、fork函数初识
1. 基本概念
fork函数是操作系统中的一个系统调用,用于创建一个新的进程,该进程是调用fork函数的进程的一个副本。新创建的进程称为子进程,原始进程称为父进程。
fork函数的函数原型:
#include <unistd.h>pid_t fork(void);
2. fork函数返回值
-
父进程中的返回值:
- 如果
fork函数返回一个大于0的值,表示当前执行的是父进程。这个返回值是子进程的PID(进程ID),可以用来操作子进程。 - 如果
fork函数返回-1,表示创建子进程失败,通常是因为系统资源不足或权限不够等原因,此时应该处理错误情况。
- 如果
-
子进程中的返回值:
- 如果
fork函数返回0,表示当前执行的是子进程。可以根据需要在子进程中执行相应的任务逻辑。
- 如果
根据fork函数的返回值,可以在程序中使用条件语句来区分父进程和子进程的不同逻辑,从而实现不同的处理方式。例如,可以在父进程中等待子进程的完成,或者在子进程中执行某种特定的任务。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>int main() {pid_t pid = fork();if (pid > 0) {// 父进程逻辑printf("This is the parent process. Child's PID: %d\n", pid);} else if (pid == 0) {// 子进程逻辑printf("This is the child process. Parent's PID: %d\n", getppid());} else {// fork失败fprintf(stderr, "Failed to create child process.\n");return 1;}// 父子进程共享的代码printf("This message is printed by both parent and child processes.\n");return 0;
}
需要注意的是,fork函数的使用可能会导致代码的分支,需要小心处理父子进程之间共享的资源以及避免产生竞争条件,以确保程序的正确性和可靠性。
二、fork函数的写时拷贝
fork函数的写时拷贝(Copy-on-Write,COW)是一种优化策略,用于在创建子进程时避免立即复制父进程的整个地址空间,这种机制可以提高性能和减少内存消耗。
在传统的fork操作中,父进程会创建一个子进程,并且子进程会复制父进程的所有资源,包括内存空间、文件描述符等。这样的完全复制操作非常消耗时间和内存。而使用写时拷贝机制,只有在需要修改共享的内存页时才会进行复制操作,从而节省了系统资源。
具体来说,当调用fork函数创建子进程时,操作系统会执行以下步骤:
- 父进程会创建一个与自己拥有相同地址空间的子进程。
- 子进程继承了父进程的页表,这意味着它与父进程共享相同的虚拟内存地址空间。
- 在初始阶段,父进程和子进程共享所有的物理页面,这些页面被标记为“只读”。
- 当父进程或子进程尝试修改共享的内存页时,操作系统会将相应的页面复制到一个新的物理页面,并将其标记为“可写”。
- 父进程和子进程现在各自拥有一个独立的物理页面,它们不再共享相同的数据。
通过写时拷贝技术,父进程和子进程共享大部分内存页,只在需要修改共享内存时才进行复制操作。这样可以节省时间和内存,并提高系统性能。例如,在fork之后,如果子进程立即执行exec函数加载了一个新的程序,那么就不需要进行任何复制操作,这是因为子进程并不需要修改父进程的内存数据。

需要注意的是,写时拷贝只是在逻辑上实现了共享,而不是物理上的共享。父进程和子进程仍然拥有各自独立的虚拟地址空间,它们之间的共享是通过允许读取相同的物理内存来实现的,只有在修改时才会发生内存复制。
总结起来,fork函数的写时拷贝机制使得父进程和子进程在初始阶段共享相同的内存空间,只有在需要修改共享内存时才进行复制操作,从而提高了性能和降低了资源消耗。
三、总结
我们首先了解了fork函数的基本概念。fork函数是操作系统中的一个系统调用,用于创建一个新的子进程。父进程调用fork函数后,会创建一个与自己拥有相同地址空间的子进程,这包括了代码、数据、堆栈等。子进程是通过复制父进程的地址空间来实现的。我们还学习了fork函数的返回值。fork函数在父进程中返回子进程的进程ID(PID),而在子进程中返回0。通过这个返回值,我们可以在父子进程中进行不同的处理逻辑。
在第二部分中,我们介绍了fork函数的写时拷贝(Copy-on-Write,COW)机制。传统的fork操作会完全复制父进程的内存空间,这在资源消耗和性能方面可能存在问题。而使用写时拷贝机制,只有在父进程或子进程尝试修改共享的内存页时才进行复制操作,从而减少复制的次数和消耗的资源。通过写时拷贝,父进程和子进程共享大部分内存页,只有在需要修改共享内存时才进行复制操作。这种优化策略提高了性能,并减少了内存资源的消耗。需要注意的是,写时拷贝只是逻辑上的共享,父进程和子进程仍然拥有各自独立的虚拟地址空间。
这些知识有助于理解fork函数的工作原理和使用方式,以及在编写多进程程序时进行性能优化的思路。
温馨提示
感谢您对博主文章的关注与支持!如果您喜欢这篇文章,可以点赞、评论和分享给您的同学,这将对我提供巨大的鼓励和支持。另外,我计划在未来的更新中持续探讨与本文相关的内容。我会为您带来更多关于Linux以及C++编程技术问题的深入解析、应用案例和趣味玩法等。如果感兴趣的话可以关注博主的更新,不要错过任何精彩内容!
再次感谢您的支持和关注。我们期待与您建立更紧密的互动,共同探索Linux、C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!

相关文章:
Fork() 函数:“父” 与 “子” 进程的交互(进程的创建)
阅读导航 前言一、fork函数初识1. 基本概念2. fork函数返回值 二、fork函数的写时拷贝三、总结温馨提示 前言 前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C的一些知识,也学习了一些Linux的基本操作,也了解并…...
JupyterNotebook设置Python环境的方法步骤
不多说,看链接。 https://stackoverflow.com/questions/39604271/conda-environments-not-showing-up-in-jupyter-notebook conda activate myenv pip install ipykernel python -m ipykernel install --user --name myenv --display-name "Python (myenv)&q…...
腾讯云阿里云云服务器 Linux 操作系统 BT 宝塔面板快速建站教程
宝塔面板概述 宝塔面板是一款服务器管理软件,支持Windows和Linux系统,可以通过Web端轻松管理服务器,提升运维效率。总体来说,宝塔面板具有操作简单、功能丰富、安全可靠等特点,是一款非常实用的服务器管理软件。 宝塔…...
【Linux】死锁理解
什么是死锁 因为资源调度的方式不合理或者资源的稀缺性,导致进程间的相互等待。 死锁的四个必要条件:互斥条件,请求和保持条件,环路等待条件,不可剥夺条件。 死锁的预防只要破坏死锁产生的四个必要条件。通常采用预…...
基于Java所涉及的人工智能的框架
11 References: [1] Java中人工智能的框架_永远的12的博客-CSDN博客...
【力扣】三角形最小路径和
目录 题目 例子 示例 1: 示例 2: 前言 思路 思想 代码 调用的函数 主函数 所有代码 力扣提交的代码 运行结果 小结 题目 给定一个三角形 triangle ,找出自顶向下的最小路径和。 每一步只能移动到下一行中相邻的结点上。相邻的结…...
【Linux】指针常量和常量指针
这个是指针常量,不能修改指向【其实就是引用的原型】:可以理解为const是否限制了星号 这个是常量指针,可以改指向,不能改值:...
LCP 22.黑白方格画
题目来源: leetcode题目,网址:LCP 22. 黑白方格画 - 力扣(LeetCode) 解题思路: 分别计算当涂0行,1行,2行.......时能否满足要求,若能ÿ…...
Java并发编程第8讲——ThreadLocal详解
ThreadLocal无论是在项目开发还是面试中都会经常碰到,它的重要性可见一斑,本篇文章就从ThreadLocal的使用、实现原理、核心方法的源码、内存泄漏问题等展开介绍一下。 一、什么是ThreadLocal ThreadLocal是java.lang下面的一个类,在JDK 1.2版…...
2023复旦大学计算机科学技术(网络空间安全)保研记录
BG:中九rank前5%、科研经历少、无竞赛 复旦大学计算机科学与技术--网络空间安全方向,参营4天(6.26-6.29),管午饭,住宿自理 6.26--报道听会,6.27--听会+实验室参观 给了…...
linux系统通过docker安装python的jieba,如何找到jieba路径替换分词文件
1、安装python镜像 python镜像名为 jetz_python3.7.131、进入容器 首次安装镜像后,容器启动,进入容器中,其中py37是容器名称,后面会一直用到 docker run -it --name py37 jetz_python3.7.13 /bin/bash如果进入过容器退出了,而容器已存在,上面的的 命令会报错,直接根…...
Python Functions-函数
目录 创建函数 调用函数 参数还是自变量? 参数数量 任意参数,*args 关键字参数 任意关键字参数,**kwargs 默认参数值 将列表作为参数传递 The pass Statement 递归 函数是一个只有在被调用时才运行的代码块。 可以将称为参数的数…...
【人工智能】机器学习的入门与提升
目录 1.入门 1.1.从何处开始 1.2.数据集 1.3.数据类型 2.平均中位数模式 2.1.均值、中值和众数 2.2.均值 2.2.1.实例 2.2.2.运行结果 2.3.中值 2.3.1.实例 2.3.2.运行结果 2.3.3.实例 2.3.4.运行结果 2.4.众数 2.4.1.实例 2.4.2.运行结果 2.5.章节总结 3.标准…...
WEB漏洞原理之---【XMLXXE利用检测绕过】
文章目录 1、概述1.1、XML概念1.2、XML与HTML的主要差异1.3、XML代码示例 2、靶场演示2.1、Pikachu靶场--XML数据传输测试玩法-1-读取文件玩法-2-内网探针或攻击内网应用(触发漏洞地址)玩法-3-RCE引入外部实体DTD无回显-读取文件开启phpstudy--apache日志…...
element-table排序icon没有点亮
<el-table :data"tableData" ref"tableRef"border :sort"defaultSort":default-sort"defaultSort"><el-table-column sortable :sort-orders"sortOrder" prop"date" label"日期"> </el-…...
传统的经典问题 Java 的 Interface 是干什么的
传统的经典问题 Java 的 Interface 是干什么 解答 上面的这个问题应该还是比较好回答的吧。 只要你做过 Java ,通常 Interface 的问题多多少少会遇到,而且可能会遇到一大堆。 在JAVA编程语言中是一个抽象类型(Abstract Type)&…...
Linux 文件 目录管理
Linux 文件 基本属性 Linux 系统是一种典型的多用户系统,为了保护系统的安全性,不同的用户拥有不同的地位和权限。Linux 系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定。 可以使用命令:ll 或 ls –…...
QT信号槽实现原理
定义Q_OBJECT宏 在宏中声明了几个重要的成员变量及成员函数,包括声明了一个只读的静态成员变量static MetaObject,以及3个public的成员函数 static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void …...
7-7 求鸡兔数量
老张家养了很多鸡和兔,圈养在一个笼子里,清早起来老张站在笼子旁边数了数头的个数,蹲下来又数了数脚的个数,你能帮他快速算出来鸡兔各有多少只吗?如实在算不出来, 就提示“error” 输入格式: 输入头的个数…...
CTF 全讲解:[SWPUCTF 2022 新生赛]webdog1__start
文章目录 参考环境题目learning.php信息收集isset()GET 请求查询字符串全局变量 $_GET MD5 绕过MD5韧性脆弱性 md5()弱比较隐式类型转换字符串连接数学运算布尔判断 相等运算符 MD5 绕过科学计数法前缀 0E 与 0e绕过 start.php信息收集头部检索 f14g.php信息收集 探秘 F1l1l1l1…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
