当前位置: 首页 > web >正文

fork详解(附经典计算题)

概念

fork 函数可以创建一个新的进程,称为子进程,而调用 fork 的进程则为父进程。子进程是父进程的副本,它会获得父进程数据空间、堆、栈等资源的副本,但父子进程拥有相互独立的地址空间。这意味着,虽然子进程复制了父进程的这些资源,但后续父子进程对这些资源的修改不会相互影响 。同时,父子进程会共享父进程中打开的文件描述符,即父、子进程中相同编号的文件描述符在内核中指向同一个 file 结构体,file 结构体的引用计数会增加。

函数原型及返回值

函数原型:pid_t fork(void) ,该函数不需要传入参数。其中pid_t本质是int类型,在#include <sys/types.h>中定义,同时还需要包含头文件#include <unistd.h> 。
返回值:具有 “调用一次,返回两次” 的特点。如果创建子进程成功,在父进程中,fork 返回新创建子进程的进程 ID(大于 0 的整数);在子进程中,fork 返回 0。如果创建子进程失败,fork 返回 - 1,此时可以通过errno查看具体的错误原因,比如达到进程数上限(EAGAIN) 、没有足够空间给新进程分配(ENOMEM)等。

工作机制

当父进程调用 fork 函数时,操作系统会复制当前父进程的状态信息,包括代码段、数据段、堆栈指针、寄存器值等。子进程从 fork 函数调用之后的下一条指令开始执行。不过,在不同的 Linux 系统下,无法确定 fork 之后是子进程先运行还是父进程先运行,这取决于系统的调度策略。

实际应用场景

多任务处理:例如网络服务器程序中,父进程可以负责监听客户端的连接请求,每当有新的请求到来,就调用 fork 创建子进程,由子进程来处理具体的客户端请求,而父进程继续监听新的连接,这样可以实现并发处理多个客户端请求 。
执行不同程序 :shell 在执行命令时会用到 fork。子进程从 fork 返回后,可以调用 exec 系列函数,用新的程序替换当前进程的内存映像,从而执行不同的程序。在 UNIX 系统中,fork 和 exec 是分开的,这使得子进程在 fork 和 exec 之间有机会更改自身属性,如进行 I/O 重定向、修改用户 ID、安排信号处理等操作。

示例

fork();                    // 第1个fork
fork() && fork() || fork(); // 第2、3、4个fork(组合)
fork();                    // 第5个fork

不算main进程,共产生19个子进程

将上述5个fork分别记为F1、F2、F3、F4、F5。

F1产生一个子进程,F5将进程翻倍,重点考虑中间的3个,熟悉fork的返回值即可判断,&&只有当左边为真才考虑右边,||只有当左边为假才考虑右边

image-20250830160358792

如图,main进程下得到5个执行到F5的进程,同理F1也可得到5个,共10个,F5再翻倍,共20个,减去1个main进程共19个子进程

http://www.xdnf.cn/news/19413.html

相关文章:

  • 苍穹外卖项目笔记day02
  • Rust 登堂 之 Sized和不定长类型 DST(七)
  • leetcode刷题记录08——top100题里的5道中等题
  • Vue基础知识-methods事件绑定(@事件名和v-on:事件名)和常用事件修饰(.prevent/.stop/.once/.enter)
  • Coze源码分析-API授权-删除令牌-后端源码
  • 【15】VisionMaster入门到精通——--通信--TCP通信、UDP通信、串口通信、PLC通信、ModBus通信
  • 鸿蒙ArkTS 核心篇-16-循环渲染(组件)
  • lvgl模拟器 被放大 导致显示模糊问题
  • Notepad++使用技巧1
  • 日志ELK、ELFK、EFK
  • 快速学习和掌握Jackson 、Gson、Fastjson
  • AI + 行业渗透率报告:医疗诊断、工业质检领域已进入规模化落地阶段
  • GD32入门到实战20--定时器
  • 【LeetCode】大厂面试算法真题回忆(122) —— 篮球比赛
  • react性能优化有哪些
  • SSR降级CSR:高可用容灾方案详解
  • Android中handler机制
  • 【Android】JSONObject和Gson的使用
  • HTTP的概念、原理、工作机制、数据格式和REST
  • 《C++——makefile》
  • 三重积分的性质
  • 【MATLAB绘图进阶教程】(2-6)动态绘图制作详解与例程,包括drawnow、pause、getframe、video write等命令
  • 机器学习时间序列算法进行随机划分数据是不合适的!
  • Dify1.8.0最新版本安装教程:Ubuntu25.04系统本地化安装部署Dify详细教程
  • 移动零,leetCode热题100,C++实现
  • IP-Guard支持修改安全区域密级文字和密级级数
  • 嵌入式学习日记(38)HTTP
  • Java学习笔记-多线程基础
  • Kafka 4.0 生产者配置全解析与实战调优
  • Go语言流式输出实战:构建高性能实时应用