fork可以用来创建一个进程,当我们在一个循环体中,就可以多次fork,创建多个进程,但是由于fork后是多进程一起执行,往往会出现令人意外的情况,请看下面的demo:
#include <stdio.h> //标准的输入输出函数
#include <stdlib.h> //standard library标准库函数头文件
#include <unistd.h> //对于类 Unix 系统,unistd.h 中所定义的接口通常都是大量针对系统调用的封装 fork、
int main()
{
pid_t pid;
int i;
for (i = 0; i < 5; ++i)
{
pid=fork();
// 这是异常情况
if (pid==-1)
{
perror("fork失败!");
exit(1);
}
}
//返回大于0的进程就是父进程
if(pid>0) //父进程
{
printf("父进程: pid= %d , ppid=%d,子进程: %d \n", getpid(),getppid(),pid);
sleep(1); //这里延迟父进程程序,等子进程先执行完。
}
else if(pid==0) //子进程
{
printf("i的变量是: %d 子进程: pid= %d , ppid=%d \n", i,getpid(),getppid());
}
return 0; //养成好习惯,返回程序执行状态码
}
执行编译后,执行输出,./a.out,输出结果如下:
总共有32个进程出来,原本是想创建五个子进程,为什么呢?
原因在于在fork后,循环体for的逻辑在子进程也会执行,这样就变成了子进程也会fork子进程,而再次循环子进程又会创建子进程,如果反复五次,是呈现指数增加的,所以是2的5次方,32个进程。
这并不是我们想要的结果,所以需要避免子进程继续fork
#include <stdio.h> //标准的输入输出函数
#include <stdlib.h> //standard library标准库函数头文件
#include <unistd.h> //对于类 Unix 系统,unistd.h 中所定义的接口通常都是大量针对系统调用的封装 fork、
int main()
{
pid_t pid;
int i;
for (i = 0; i < 5; ++i)
{
pid=fork();
// 这是异常情况
if (pid==-1)
{
perror("fork失败!");
exit(1);
}
//循环中,fork函数调用五次,子进程返回0,父进程返回子进程的pid,
//为了避免子进程也fork,需要判断并break
if (pid==0)
{
break;
}
}
//返回大于0的进程就是父进程
if(pid>0) //父进程
{
printf("父进程: pid= %d , ppid=%d,子进程: %d \n", getpid(),getppid(),pid);
sleep(1); //这里延迟父进程程序,等子进程先执行完。
}
else if(pid==0) //子进程
{
printf("i的变量是: %d 子进程: pid= %d , ppid=%d \n", i,getpid(),getppid());
}
return 0; //养成好习惯,返回程序执行状态码
}
执行编译后,执行输出,./a.out,输出结果如下:
以上是学习linux编程基础一书的笔记。