关于fork()||fork();

来源:互联网 发布:美萍 sql 编辑:程序博客网 时间:2024/05/16 09:06

        今天到实验室一个同学问了我这个问题,说是今年阿里的笔试题,问 fork()||fork();这条语句执行后,一共生成了几个子进程。刚看到的时候懵了一下,然后仔细的想了想,这其实是在从语法和linux系统知识两个方面在考察,平时写程序的时候,&&或||这类判断可谓经常用到,但是很少去考虑其细节,所以他问我的时候一时间还真不知道怎么下手,于是写了个简单的程序测试了一下。

#include <stdio.h>#include <unistd.h>int main(){    fork()||fork();    printf("created a process\n");    return 0;}
        打印结果如下:

created a processcreated a processcreated a process

        很显然,这条语句创建了3个进程,那么这是为什么呢?

        思考了一下决定还是从本质开始分析,例如一个逻辑判断语句:

a || b<pre name="code" class="cpp">a && b

       以前在我的脑海里,只会简单思考:a和b只要有一个为1,那么结果就是1,否则是0,然而这个运算符是有过程的,具体过程如下:

       对于a||b:

  • a为1时,就不需要再判断b,则表达式值为1
  • a为0时,需脚再判断b,如果b为1,则表达式值为0
       同理对于a&&b:
  • a为1时,继续判断b,如果都为1,则表达式为1,否则为0
  • a为0时,不在判断b,表达式为0
        有了这个思路,fork()||fork()就很简单了:
        我们知道fork()在子进程中返回0,在父进程中返回大于0的子进程pid,因此,在不出错(即返回-1的情况下)
        假设第一个创建的进程号为1,那么1在执行第一个fork()时,在自身进程中返回>0,不再判断||后的表达式
        而此时,由1进程创建的子进程2中fork()返回为0,因此需要继续执行||后的表达式,也就是第二个fork(),于是就产生了子进程3.

        总的来说,就是1执行了一次fork(),生成了子进程2,而子进程2又执行了一次fork(),于是生成了子进程3,共三个进程。
        所以,对于fork()&&fork()也可以用同样的方法分析,甚至可以扩展到forkI()||fork()&&fork()...
        其实这种fork的关系可以用一个二叉树来很清晰的表示:
       
        为了方便,始终把父进程放在左侧,可以看到,最终生成的进程数量,就是这颗二叉树的叶子数目了。
0 0