进程篇:循环创建N个子进程

进程篇:循环创建N个子进程

标签:fork();N个子进程

从前面的进程篇——fork()可以了解到fork函数会创建父进程和子进程,并且他们在执行的时候,怎么来控制说是先创建父进程,还是先创建子进程呢?其实根据计算机原理来说,父子进程抢占cpu,谁先得到就谁先执行,其实也有一种说法,是父进程先执行的可能性比较大,但是没有理论依据。好了,费话不多说,我们来看代码。
首先,我们先看这样的一段代码:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5     int i;
  6     pid_t pid;
  7 //  for(i=0;i<5;i++)
  8 //  {
  9         pid = fork();
 10         if(pid==-1)
 11             perror("error\n");
 12         else if(pid==0)
 13             printf("child,pid=%u,ppid=%u\n",getpid(),getppid());
 14         else{
 15 //          sleep(1);                                                       
 16             printf("father,pid=%u,ppid=%u\n",getpid(),getppid());
 17             }
 18 //      }
 19         return 0;
 20  
 21 }

这段代码其实很简单,但是大家看一下结果,就会有问题了:
image
从这个结果,我们可以看出的是,结果输出为什么会出现在命令行中,而不是像平时代码一样,执行完后出现命令行,但是这个确出现在了命令行。我们用命令查看一下,输入命令:

ps aux | grep 2669

得到的结果是:

wz        2669  0.0  0.3   8512  3468 pts/0    Ss   10:21   0:00 bash
wz        6391  0.0  0.0   6124   824 pts/0    S+   20:41   0:00 grep --color=auto 2669

看到这个2669这个进程是bash进程的进程号: 所以产生上面的现象的原因是:
在产生这么多的子进程的时候,bash是不知道这么多的子进程和孙子进程的,在开始的shell命令行中,我们使用./fork的命令,然后shell进程把自己切入到后台,前台是给了fork程序来使用的,shell进程收回前台的命令是在它执行完之后,也就是儿子进程执行完之后,shell会收回前台,在父进程return之后,shell进程就把前台收回了,然后再进入命令行模式中,等待用户输入命令,所以会出现这样的情况,所以解决办法就是保证shell的子进程在最后结束。
好了,解决完上面的问题,我们来看循环子进程的问题。对于循环子进程来说,我们很容易就知道,我们需要fork()函数执行N次,我们用3次来模拟,代码如下:

 1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5     int i;
  6     pid_t pid;
  7     for(i=0;i<3;i++)
  8     {
  9         pid = fork();
 10         if(pid==-1)
 11             perror("error\n");
 12         else if(pid==0)
 13             printf("i am %dth child,pid=%u,ppid=%u\n",i+1,getpid(),getppid()    );                                                                          
 14         else{
 15             sleep(1);
 16             printf("i am %dth father,pid=%u,ppid=%u\n",i+1,getpid(),getppid(    ));
 17             }
 18         }
 19         return 0;
 20  
 21 }

得到的结果为:

i am 1th child,pid=7222,ppid=7221
i am 2th child,pid=7223,ppid=7222
i am 3th child,pid=7224,ppid=7223
i am 1th father,pid=7221,ppid=2669
i am 2th father,pid=7222,ppid=7221
i am 3th father,pid=7223,ppid=7222
i am 2th child,pid=7225,ppid=7221
i am 3th child,pid=7226,ppid=7222
i am 3th child,pid=7227,ppid=7225
i am 2th father,pid=7221,ppid=2669
i am 3th father,pid=7222,ppid=7221
i am 3th father,pid=7225,ppid=7221
i am 3th child,pid=7228,ppid=7221
i am 3th father,pid=7221,ppid=2669

看起来比较凌乱。但是为什么会出现这么多,我们通过一张图来看一下:
image
从这图很容易看出来子进程产生的过程。
上面的程序我们修改一下,就可以很准确的看到有几个子进程被创建:

 1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5     int i;
  6     pid_t pid;
  7     for(i=0;i<5;i++)
  8     {
  9         pid = fork();
 10         if(pid==-1)
 11             perror("error\n");
 12         else if(pid==0)
 13         {
 14             break;
 15         }
 16     if(i<5)                                                                 
 17     {
 18         sleep(i);
 19         printf("i am %dth child\n",i+1);
 20     }
 21     else
 22     {
 23         sleep(i);
 24         printf("i am parent\n");
 25     }
 26     }
 27         return 0;
 28     
 29 }                   

结果为:

i am 1th child
i am 2th child
i am 3th child
i am 4th child
i am 5th child

这就看起来比较明显了。

猜你喜欢

转载自blog.csdn.net/Travelerwz/article/details/80304488