fork创建多个子进程
示例代码
fork1.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc,char **argv)
{
int i, j;
pid_t pid;
for (i = 0; i < 3; i++)
{
pid = fork();
if (pid < 0)
{
perror("fork()");
exit(1);
}
if (pid == 0) //child
{
printf("Child is [%d]!\n",getpid());
}
}
//为了方便分析添加sleep函数
sleep(1000);
exit(0);
}
运行结果
编译执行,如下图所示:
计算创建进程的数量
不是创建3个子进程吗?上图中创建了(即2^3-1)7个子进程,加上父进程一共8个进程。这是因为在pid=6047即main进程,使用fork创建了3个子进程,这3个子进程没有直接退出,又分别调用fork创建子进程。
将上图整理分析如下图所示:
从上图我们可以看出来,原因是创建的子进程也调用了fork函数,要是想创建3个子进程,将创建的子进程调用exit(),就能避免子进程再次调用fork的问题。
进程的状态:
在子进程区域添加exit,我们看下进程的状态
fork1.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc,char **argv)
{
int i, j;
pid_t pid;
for (i = 0; i < 3; i++)
{
pid = fork();
if (pid < 0)
{
perror("fork()");
exit(1);
}
if (pid == 0) //child
{
printf("Child is [%d]!\n",getpid());
sleep(1000);
//要让子进程退出
exit(0);
}
}
//将sleep放到这里
//sleep(1000);
exit(0);
}
在子进程退出前,调用sleep(1000),让父进程先结束,观察进程的状态,在终端输入如下命令
ps axf
如下图所示
从上图可看出进程的状态是S+,即可中断的睡眠态。具体其他的状态可man ps
看手册中解释如下:
将上述代码中子进程中的sleep(1000)注释掉,sleep(1000)函数放到for循环外,编译执行代码,在终端输入如下命令,查看进程的状态
ps axf
如下图所示
当前父进程的状态是S+,可中断的睡眠态,子进程状态是Z+,僵尸态。造成这种是因为子进程先死(退出)啦,但是现在父进程还在sleep()没来的及收尸,子进程现在就是僵尸态。
父进程回收子进程,主要是pid号有限的,要回收,子进程的僵尸态,其实占用不了多少资源,
孤儿进程:
当父进程先于子进程结束,活着的子进程就变为孤儿进程,孤儿进程会被init进程收养。
僵尸进程:
子进程结束,父进程还没有回收。