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

一道“fork + 短路求值”经典题:到底会创建多少个进程?

问题描述

代码如下(不算main进程本身,问总共创建了多少个子进程):

intmain(intargc,char*argv[]){fork();fork()&&fork()||fork();fork();}

选项:A.18 B.19 C.20 D.21


先把结论放前面

  • 程序最终一共会有20 个进程(包含最初的main进程)
  • 因为题目要求“不算main进程本身”,所以创建的子进程数为:20 - 1 = 19
  • 正确选项:B.19

必备知识点:fork 返回值 + C 里的真假

1)fork()做了什么?

fork()会复制当前进程,产生一个子进程:

  • 父进程中,fork()返回子进程 pid(>0)
  • 子进程中,fork()返回0
  • 失败返回 -1(本题默认不考虑失败)

2)C 语言中真假如何判断?

  • 0表示假(false)
  • 非 0表示真(true)

所以:

  • 父进程里fork()的返回值为真
  • 子进程里fork()的返回值为假

本题的灵魂:&&/||的短路求值 + 优先级

1)优先级

在 C 语言里:&&的优先级高于||

因此这句:

fork()&&fork()||fork();

等价于:

(fork()&&fork())||fork();

2)短路规则(务必牢记)

  • A && B:如果A为假,则不再计算 B
  • A || B:如果A为真,则不再计算 B
  • 运算从左到右求值

逐行计算:进程数怎么变

我们按“每一行执行后,进程数乘几”来算。

第 1 行:fork();

每个进程执行一次fork(),都会一分为二:

  • 1 个进程 → 2 个进程
  • 也就是:×2

第 2 行:(fork() && fork()) || fork()

这一行最容易错。关键点:不同分支会不会继续执行后面的fork(),取决于短路。

下面用“一个进程进入这一行”为例,算这一行最终会变成多少个进程。

可视化流程图(Mermaid)

父: pid为正 真

子: 返回0 假

父: pid为正 真

子: 返回0 假

进入表达式

fork1

进入 AND 右侧

AND 短路,进入 OR 右侧

fork2

左侧为真,OR 短路

左侧为假,执行 fork3

fork3

fork3

结束

结束

结束

用“分支计数法”数进程

设进入这一行前只有 1 个进程:

  1. 先执行第一个fork()(记作 F1)

    • 变成2 个进程
    • 父进程:F1 返回真
    • 子进程:F1 返回假
  2. 对父进程(F1 为真):

    • 需要继续算&&右侧,于是执行第二个fork()(F2)
    • F2 又把该父分支变成2 个进程
      • F2 父:true && true为真 →||短路 →不执行第三个 fork
      • F2 子:true && false为假 → 进入||右侧 →会执行第三个 fork(F3),再分裂一次
  3. 对子进程(F1 为假):

    • &&短路:第二个fork()不执行
    • 直接进入||右侧:会执行第三个fork()(F3),再分裂一次

把最终的进程数列一下(从 1 个进程进入该行开始):

  • F1 父 + F2 父:1 个(不会执行 F3)
  • F1 父 + F2 子:会执行 F3 → 2 个
  • F1 子:会执行 F3 → 2 个

总计:1 + 2 + 2 = 5

所以这一行的效果是:

  • ×5

经验化记忆:(fork() && fork()) || fork()每个进入的进程最终会变成 5 个。


第 3 行:fork();

最后一行再次每个进程一分为二:

  • ×2

汇总:最终进程数与创建进程数

设最开始只有 1 个main进程:

语句乘法因子执行后总进程数
初始-1
fork();×22
(fork() && fork())fork();×510
fork();×220
  • 最终总进程数(包含main):20
  • 创建的子进程数(不算main):20 - 1 = 19

常见坑位总结

  1. 忘了&&优先级高于||,没加括号就按错误方式理解表达式
  2. 忘了短路:以为每个分支都会把三个fork()全执行
  3. 忘了题目“不算main进程本身”:最终进程数要再减 1

小结

这类题的核心不是“fork 有多难”,而是:

  • fork()在父子进程中的返回值真假不同
  • && / ||的短路会让某些分支“跳过 fork”,从而改变进程增长倍率
http://www.jsqmd.com/news/311433/

相关文章:

  • UVa 142 Mouse Clicks
  • 金仓数据库KingbaseES 归档日志清理
  • 《MyBatis 从入门到上手:超全基础操作 + XML 配置指南》 - 教程
  • 细聊浙江退磁器价格,哪家产品性价比高?
  • 分析形象设计学校靠谱推荐,武汉新华学费多少钱
  • 2026天津用工风险法律机构排名揭晓,口碑好的律所都在这
  • 2026年杭州靠谱的AI营销公司排名,宇森GEO优化性价比值得关注
  • 2026年山西太原靠谱的断桥铝系统门窗服务商排名,科典门窗实力上榜
  • 分析微型小挖加工厂,济宁售后好的有哪些
  • 使用mysqldumpslow分析特定数据库用户的慢查询
  • 质感砖推荐,斯米茄打造静谧奢华空间效果怎么样?
  • 探寻罗蒙官网电话和主页,来样定制性价比排名
  • 2026年北京地区口碑好的大平层装修企业排名
  • 聊聊低温减速机厂家,鑫钺传动是不是优质之选?
  • 2026年哈尔滨口碑不错的管道疏通专业公司排名,哪家性价比更高?
  • 基于Spring Boot的驾校管理系统的设计与实现(毕业论文)
  • 亿图图示 v15 破解版下载及安装使用教程
  • 探讨客厅沙发家具店价格和性价比,南浔这家店口碑佳
  • 玻璃钢夹砂管道制造厂选哪家好,性价比厂家Top10
  • 分析超细纤维品牌制造商排名,柏丁达在广东排第几?
  • 飞斯达市场口碑怎么样,2026年黑龙江配电箱公司Top10
  • 黑龙江配电柜安装与采购费用分析,选飞斯达更划算
  • 江浙沪皖鲁国际高中留学本科选哪家,京岛义塾值得考虑
  • 第1章 人工智能:过去、现在与未来
  • 用户态/内核态 = 操作系统内核?
  • 《HelloGitHub》第 118 期
  • 基于Python进行人脸识别控制小灯闪烁(识别到指定人脸)
  • 神经网络深度解析:从神经元到深度学习的进化之路 - 教程
  • 详细介绍:深度学习理论与实战:用生活案例理解回归模型
  • 行为型设计模式:借助某个对象来协调多对象交互的中介者模式,不允许你不知道!