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函数返回值

  1. 父进程中的返回值:

    • 如果fork函数返回一个大于0的值,表示当前执行的是父进程。这个返回值是子进程的PID(进程ID),可以用来操作子进程。
    • 如果fork函数返回-1,表示创建子进程失败,通常是因为系统资源不足或权限不够等原因,此时应该处理错误情况。
  2. 子进程中的返回值:

    • 如果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函数创建子进程时,操作系统会执行以下步骤:

  1. 父进程会创建一个与自己拥有相同地址空间的子进程。
  2. 子进程继承了父进程的页表,这意味着它与父进程共享相同的虚拟内存地址空间。
  3. 在初始阶段,父进程和子进程共享所有的物理页面,这些页面被标记为“只读”。
  4. 当父进程或子进程尝试修改共享的内存页时,操作系统会将相应的页面复制到一个新的物理页面,并将其标记为“可写”。
  5. 父进程和子进程现在各自拥有一个独立的物理页面,它们不再共享相同的数据。

通过写时拷贝技术,父进程和子进程共享大部分内存页,只在需要修改共享内存时才进行复制操作。这样可以节省时间和内存,并提高系统性能。例如,在fork之后,如果子进程立即执行exec函数加载了一个新的程序,那么就不需要进行任何复制操作,这是因为子进程并不需要修改父进程的内存数据。
在这里插入图片描述

需要注意的是,写时拷贝只是在逻辑上实现了共享,而不是物理上的共享。父进程和子进程仍然拥有各自独立的虚拟地址空间,它们之间的共享是通过允许读取相同的物理内存来实现的,只有在修改时才会发生内存复制。

总结起来,fork函数的写时拷贝机制使得父进程和子进程在初始阶段共享相同的内存空间,只有在需要修改共享内存时才进行复制操作,从而提高了性能和降低了资源消耗。

三、总结

我们首先了解了fork函数的基本概念。fork函数是操作系统中的一个系统调用,用于创建一个新的子进程。父进程调用fork函数后,会创建一个与自己拥有相同地址空间的子进程,这包括了代码、数据、堆栈等。子进程是通过复制父进程的地址空间来实现的。我们还学习了fork函数的返回值。fork函数在父进程中返回子进程的进程ID(PID),而在子进程中返回0。通过这个返回值,我们可以在父子进程中进行不同的处理逻辑。

在第二部分中,我们介绍了fork函数的写时拷贝(Copy-on-Write,COW)机制。传统的fork操作会完全复制父进程的内存空间,这在资源消耗和性能方面可能存在问题。而使用写时拷贝机制,只有在父进程或子进程尝试修改共享的内存页时才进行复制操作,从而减少复制的次数和消耗的资源。通过写时拷贝,父进程和子进程共享大部分内存页,只有在需要修改共享内存时才进行复制操作。这种优化策略提高了性能,并减少了内存资源的消耗。需要注意的是,写时拷贝只是逻辑上的共享,父进程和子进程仍然拥有各自独立的虚拟地址空间。

这些知识有助于理解fork函数的工作原理和使用方式,以及在编写多进程程序时进行性能优化的思路。

温馨提示

感谢您对博主文章的关注与支持!如果您喜欢这篇文章,可以点赞、评论和分享给您的同学,这将对我提供巨大的鼓励和支持。另外,我计划在未来的更新中持续探讨与本文相关的内容。我会为您带来更多关于Linux以及C++编程技术问题的深入解析、应用案例和趣味玩法等。如果感兴趣的话可以关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。我们期待与您建立更紧密的互动,共同探索Linux、C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!
在这里插入图片描述

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

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

相关文章

山石网科国产化防火墙,打造全方位边界安全解决方案

互联网的快速发展促进了各行各业的信息化建设&#xff0c;但也随之带来了诸多网络安全风险。大部分组织机构采用统一互联网接入方案&#xff0c;互联网出口承担着内部用户访问互联网的统一出口和对外信息服务的入口&#xff0c;因此在该区域部署相匹配的安全防护手段必不可少。…

Serverless 数仓技术与挑战(内含 PPT 下载)

近期&#xff0c;Databend Labs 联合创始人张雁飞发表了题为「Serverless 数仓技术与挑战」的主题分享。以下为本次分享的精彩内容&#xff1a; 主题&#xff1a; 「Serverless 数仓技术与挑战」 演讲嘉宾&#xff1a; 张雁飞 嘉宾介绍&#xff1a; Databend Labs 联合创始人…

vue重修002

文章目录 版权声明一 指令修饰符1. 什么是指令修饰符&#xff1f;2. 按键修饰符3. v-model修饰符4. 事件修饰符 二 v-bind对样式控制的增强-操作class1. 语法&#xff1a;2. 对象语法3. 数组语法4. 代码练习 三 京东秒杀-tab栏切换导航高亮四 v-bind对有样式控制的增强-操作sty…

代码随想录刷题 Day18

513.找树左下角的值 这个题用层序遍历比较简单&#xff0c;按照模版改一句话就可以&#xff1b;层序遍历用这个queue来实现&#xff1b; 用前序遍历的话就需要用递归比较麻烦 class Solution { public:int findBottomLeftValue(TreeNode* root) {queue<TreeNode*> que…

Oracle-ADG无法应用日志问题(Bug-17695685)

问题: Oracle11.2.0.4.5的版本&#xff0c;ADG备库mrp进程出现无法应用日志的问题 问题原因分析: 查看当前mrp进程的状态&#xff0c;当前在应用日志thread# 1 626298 select inst_id,process,thread#,sequence#,status from gv$managed_standby;备库查看日志的状态&#xf…

国密国际SSL双证书解决方案,满足企事业单位国产国密SSL证书要求

近年来&#xff0c;为了摆脱对国外技术和产品的依赖&#xff0c;建设安全的网络环境&#xff0c;以及加强我国对网络信息的安全可控能力&#xff0c;我国推出了国密算法。同时&#xff0c;为保护网络通信信息安全&#xff0c;更高级别的安全加密数字证书—国密SSL证书应运而生。…

正则表达式新解

文章目录 是什么&#xff1f;正则用法匹配单个字符匹配一组字符其他元字符核心函数 贪婪匹配和非贪婪匹配正则练习 是什么&#xff1f; 正则表达式(Regular Expression)是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff09;和特殊…

案例题概述

案例题概述 考点 考点 新教材的新增考点 第一题必做&#xff0c;之后是4选2 感觉都是记忆的&#xff0c;课件完整一些&#xff0c;之后以看课件为主了&#xff0c;不在做详细笔记了

IDEA中如何查看自己的SpringBoot的版本

直接输入代码执行&#xff1a; public class App {public static void main(String[] args) {String springVersion SpringVersion.getVersion();String springBootVersion SpringBootVersion.getVersion();System.out.println("Spring版本:"springVersion"\…

java常用API(Math,System,Runtime)

Math Math的常用方法 package myMath;public class myMath {public static void main(String[] args) {System.out.println(Math.abs(-99));//这个表示取绝对值的 打印结果为99//但是他有个bug.int最大取值范围是-2,147,483,648 到2,147,483,647System.out.println(Math.abs(-…

Linux -- 进程间通信之匿名管道

博客中涉及代码已全部上传至Gitee&#xff0c;有需要请自行下载 目录 前言通信基础管道 匿名管道第一步&#xff1a;创建管道第二步&#xff1a;创建子进程第三步&#xff1a;开始通信第四步&#xff1a;结束通信 匿名管道通信代码实现四种特殊情景 基于匿名管道的多进程控制对…

什么是城市坐标系,与国家坐标系的区别?

文章目录 先说国家坐标系什么是城市坐标系城市坐标系建设规范常见的城市坐标系 先说国家坐标系 先1954年我国建立了第一代国家大地坐标系统&#xff0c;即北京54坐标系&#xff0c;英文缩写BJ54&#xff0c;坐标原点在苏联&#xff0c;椭球参数直接拿苏联的。第一代坐标系的椭…

【C++杂货铺】一颗具有搜索功能的二叉树

文章目录 一、二叉搜索树概念二、二叉搜索树的操作2.1 二叉搜索树的查找2.2 二叉搜索树的插入2.3 二叉搜索树的删除 三、二叉搜索树的实现3.1 BinarySearchTreeNode&#xff08;结点类&#xff09;3.2 BinarySearchTree&#xff08;二叉搜索树类&#xff09;3.2.1 框架3.2.2 in…

Linux系统100条命令:关于Ubuntu和 CentOS 7 相同功能的不同的终端操作命令

安装软件包&#xff1a; Ubuntu&#xff1a;apt-get install package_name CentOS 7&#xff1a;yum install package_name 更新软件包列表&#xff1a; Ubuntu&#xff1a;apt-get update CentOS 7&#xff1a;yum update 卸载软件包&#xff1a; Ubuntu&#xff1a;apt-…

Diffusion Autoencoders: Toward a Meaningful and Decodable Representation

Diffusion Autoencoders: Toward a Meaningful and Decodable Representation (Paper reading) Konpat Preechakul, VISTEC, Thailand, CVPR22 Oral, Cited:117, Code, Paper 1. 前言 扩散概率模型 (DPM) 在图像生成方面取得了显着的质量&#xff0c;可与 GAN 相媲美。但是与…

C++ - 红黑树 介绍 和 实现

前言 前面 学习了 AVL树&#xff0c;AVL树虽然在 查找方面始终拥有 O(log N &#xff09;的极高效率&#xff0c;但是&#xff0c;AVL 树在插入 ,删除等等 修改的操作当中非常的麻烦&#xff0c;尤其是 删除操作&#xff0c;在实现当中细节非常多&#xff0c;在实现上非常难掌控…

如何套用模板制作大屏?

在山海鲸可视化的资源中心里内置了大量的二维、三维大屏模板&#xff0c;大家可以根据需要找到自己想要的模板&#xff0c;然后点击下载直接进行使用。 有需要可自行前往哔哩哔哩账号中观看相关内容的视频教程↓↓↓ 山海鲸可视化的个人空间-山海鲸可视化个人主页-哔哩哔哩视频…

cocos2dx查看版本号的方法

打开文件&#xff1a;项目根目录\frameworks\cocos2d-x\docs\RELEASE_NOTES.md 知道引擎版本号的意义&#xff1a; 1.面试中经常被问到(面试官想知道你会不会查版本号&#xff0c;你会查也不一定会去看&#xff0c;如果你去看了说明你是一个有心人&#xff0c;或者想深入研究下…

Java内存泄漏知识(软引用、弱引用等)

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 未经允许不得转载 目录 一、导读二、概览三、相关知识3.1 内存…

工作中Git管理项目和常见问题处理

工作中Git管理项目和常见问题处理 Git仓库的管理方式为什么会出现无法push到线上处理方法 Git仓库的管理方式 共用统一仓库,不同开发人员使用不同分支 步骤 下载代码 git clone <url>查看分支 git branch创建并切换分支 git checkout -b dev分支名称保持和远程分支一…