当前位置:   article > 正文

Fork函数_2个fork进程树怎么画

2个fork进程树怎么画

在学习fork 函数的时候觉得特别有意思,就写下来和大家分享。
1、创建新进程:pid_t fork(void)
获得ID号: pid ——–pid_t getpid();
ppid——–pid_t getppid();
fork 函数调用一次,返回2次(返回2个值) (就像女人结一次婚就可能会得到丈夫和孩子两个人)
fork函数调用一次,就会创建两个进程,一个是父进程,一个是子进程。
(1) 返回给子进程的是一个 0;
(2)返回给父进程的是子进程的 pid;
(3)如果出现错误,fork返回一个负值;
那么为什么要这样设返回值呢?
将子进程ID 返回给父进程:原因很简单,一个父亲可以有多个儿子,所以儿子很容易就能找到父亲,(但父亲很难找到所有的儿子)没有一个函数使一个进程可以获得所有子进程的ID。
子进程得到返回值0的原因是:一个进程只有一个父进程,所以子进程可以调用getppid,获得父进程的ID 号

当然我们对fork有了理解之后,就看看fork在代码中的实现:

    int main()
    {
         int i;
         for(i=0;i<2;i++)
         {
               if(fork()==0)
               {
                   printf("A\n");
               }
               else
               {
                   printf("B\n");
               }
       }
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这个问题我们可以通过画二叉树的方法来看:
这里写图片描述
fork 之后会产生父子进程,相当于父进程拷贝了一份给子进程,对于fork之后的代码会继续执行.
在Linux下执行代码,多执行几次,会得到不同的结果,fork之后,父子进程谁先运行呢?
谁先运行,与操作系统的进程调度算法和当前计算机环境有关。所以结果就是三个A,三个B.

比较一下下面这份代码和上面的代码的区别?

 int main()
    {
         int i;
         for(i=0;i<2;i++)
         {
               if(fork()==0)
               {
                   printf("A");
               }
               else
               {
                   printf("B");
             }
           }
     }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

细心的你肯定注意到printf 语句中没有了 \n,这涉及到输出缓冲区printf的问题:
那么什么时候printf就会输出呢?
1、遇到\n
2、fflush(stdout) 刷新缓冲区,_exit 程序结束时不刷新缓冲区
3、程序结束(exit或return)
4、缓冲区满(1024字节)
这里写图片描述
fork之后,i=0,产生父子进程,没有遇到\n,程序也没有结束,那么父进程得到的A和子进程得到的B都会在缓冲区先呆着,i=1时,又fork一次,父子进程会把自己的在拷贝一份给他们各自的子进程,那么拷贝的时候就包含了呆在缓冲区里的东西,所以i=2,程序结束,输出缓冲区里的东西,就是4个A,4个B哦,这种类型的题会在面试题中出现哦!!

看看下面这道题:

int main()
{
     if(fork() || fork())
               printf("A\n");
      else
               printf("B"\n);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这个和 ||操作符有关系,就不多说了。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号