• 正文
  • 相关推荐
申请入驻 产业图谱

面试题: 三行fork代码-90%的人算不对进程数

07/07 08:30
135
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

大家好,我是仲一。

之前有读者找我模拟面试,我问了一道题:

int main()
{
    fork();
    fork() && fork() || fork();
    fork();
}

不算 main 进程本身,一共创建了多少个新进程?

对方想了挺久,最后给了一个数字。我问怎么算出来的,说不太清楚。这不怪他——这道题同时考两个知识点,漏一个就算不对。

这道题是兆易创新校招笔试的原题。借它把 fork 和短路运算一次说清楚。

fork 的基本规则

fork 调用一次返回两次。父进程里返回子进程的 PID,子进程里返回 0。返回负数说明创建失败。

pid_t pid = fork();
if (pid == 0) {
    // 子进程
} else if (pid > 0) {
    // 父进程
}

短路规则

&& 左边是假,右边就不看了。左边是真,才继续看右边。

|| 左边是真,右边就不看了。左边是假,才继续看右边。

解这道题就靠这两条。

逐行推导

拆成三行来看。

第 1 行:fork()

进程翻倍。1 个变 2 个,新增 1 个。

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

这是核心。每个进程执行到这行时,都要按短路规则算。

第一个 fork 跑完,每个进程变成两个。一个返回 0(子进程),一个返回非 0(父进程)。

返回非 0 的进程,在 && 语境下算"真",继续执行第二个 fork。第二个 fork 再一分为二。

返回 0 的进程,在 && 语境下算"假",&& 短路了,第二个 fork 不执行。但表达式还没完——后面还有 |||| 左边是假,所以第三个 fork 必须执行。

这里容易想错的是:第二个 fork 产生的子进程里,fork 返回 0。这个子进程里的 && 也是假,所以它也会去执行第三个 fork。

走完这条链,第二行三个 fork 总共新增了 8 个进程。

第 3 行:fork()

到这一行一共有 10 个进程(原始 1 + 第一行 1 + 第二行 8)。每个再 fork 一次,新增 10 个。

加起来:1 + 8 + 10 = 19。

常见的错误答案

有人算 30,有人算 24。

30 是把中间行当成三个独立 fork 来算,没考虑短路。24 是少算了一层。

不信的话,把代码在 Linux 上跑一遍,数一下进程数就清楚了。

面试官可能会追问

fork 之后父子进程谁先执行? 不确定,取决于调度器。

子进程继承了哪些东西? 文件描述符、信号处理方式、环境变量——但地址空间是自己的(写时复制)。

怎么用 fork 创建固定数量的子进程? 配合循环,fork 返回 0 时 break 出来,不然子进程会继续 fork。


题目聊完了,思路应该清楚了。

你第一次算出来是几个?留言说说。

 

end

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

作者就职于某500强公司,担任BSP工程师。具有丰富的嵌入式开发经验。专栏主要分享计算机基础,操作系统,Linux驱动开发,Arm体系与架构,C/C++,数据结构与算法等相关文章。欢迎关注我的公众号【嵌入式与Linux那些事】,一起学习交流。