fork()
一、什么是fork
fork()是将当前进程复制一份生成一个子进程,被复制的进程叫做父进程,复制得来的进程叫做子进程,父子除过返回值不同之外,其他的所有都相同。
在父进程中,fork()的返回值是子进程的id号,在子进程中,fork()的返回值为0。
fork()的作用是复制进程(或者说创建进程)。
man fork
通过查看fork的文件之后,发现fork的作用是创建一个进程,fork的头文件是 unistd.h ,fork是无参的,其返回类型是pid。
补充一点:在Linux中,要产生一个新的进程分两步走,fork+exec。即先通过fork复制,然后再通过exec替换。这里只讲fork,exec在后面会提到。
二、实列
2.1 例1
通过一个实列来看fork:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include<unistd.h>
int main()
{
int n =0;
char *s = NULL;
pid_t pid = fork();
assert(pid!=-1);
if(pid==0)
{
n=3;
s="child";
}
else
{
n=7;
s="parent";
}
int i=0;
for(;i<n;++i)
{
printf("s=%s",s);
sleep(1);
}
exit(0);
}
分析:
当父进程执行到fork()的时候,复制出子进程。因为父进程中,fork的返回值为子进程的id,所以父进程中n=7;子进程中,fork的返回值为0,所以,子进程中n=3,又因为在fork完成以后,默认父子进程是并发(同时进行)执行的,父子进程相互不影响(子进程的结束不会影响到父进程),所以父子进程一起执行,当子进程执行到n=3的时候,子进程结束,父进程继续进行,直到父进程执行到n=7结束进程。
通过gcc编译之后,运行代码发现结果为:
图解:
注意:在父进程执行过的fork,子进程中会从fork后面的位置开始执行
为了进一步观察父子进程的id号,将代码改一下:
int n =0;
char *s = NULL;
pid_t pid = fork();
assert(pid!=-1);
if(pid==0)
{
n=3;
s="child";
}
else
{
n=7;
s="parent";
}
int i=0;
for(;i<n;++i)
{
printf("s=%s,curr_pid=%d,ppid=%d\n",s,getpid(),getppid());
sleep(1);
}
执行结果:
可以看到子进程的id为3159,父进程的id为3158。
子进程的id大于父进程的id
2.2 例2
int main()
{
int i=0;
for(;i<2;++i)
{
fork();
printf("A\n");
}
exit(0);
}
分析:
运行结果: