fork()顾名思义是分支的意思,也就是克隆程序后面的代码至新的进程中,直接上程序:
#include <unistd.h>
#include <stdio.h>
int main()
{
pid_t fpid; //fpid表示fork函数返回的值
int count = 0;
fpid = fork();
if (fpid < 0)
printf("error in fork!");
else if (fpid == 0) {
printf("i am the child process, my process id is %d\n", getpid());
printf("I am son\n");
count++;
}
else {
printf("i am the parent process, my process id is %d\n", getpid());
printf("I am father\n");
count++;
}
printf("result: %d\n", count);
return 0;
}
运行结果:
i am the parent process, my process id is 10742
I am father
result: 1
i am the child process, my process id is 10743
I am son
result: 1
可以看出,fork确实开了两个进程,将之后的代码复制到另一个进程中去执行,也线程不同,进程中的程序并不会共享变量等资源,因此这里同时满足了两个对立的条件。其中,父进程的fpid值不为零,子进程fpid为零,可以通过这点来区分父进程和子进程。
那么,如果fork()用在循环中会怎么样了,会将循环到额判断条件写入子进程吗?
#include <unistd.h>
#include <stdio.h>
int main() {
for (int i = 0; i <2; i++) {
pid_t fpid = fork();
if (fpid == 0)
printf("%d child %4d %4d %4d\n", i, getppid(), getpid(), fpid);
else
printf("%d parent %4d %4d %4d\n", i, getppid(), getpid(), fpid);
}
return 0;
}
运行结果:
0 parent 11041 11044 11045
0 child 11044 11045 0
1 parent 11041 11044 11046
1 child 11044 11046 0
1 parent 11044 11045 11047
1 child 11045 11047 0
可以看出,pid号有点像链表的原理,将父子进程链接在一起,例如:
11041->11044->11045->0
这是由同一次产生的父子进程,而同一类进程除了当前的fpid不同,其他id均相同。所以循环中的fork可以理解为二叉树结构,该程序执行了6次printf函数。
那我们再看一个例子:
#include <unistd.h>
#include <stdio.h>
int main() {
for (int i = 0; i <3; i++) {
fork();
printf("%d cc\n",i);
}
return 0;
}
请问打印了几个cc,具体是如何打印?
运行结果:
0 cc
0 cc
1 cc
1 cc
1 cc
2 cc
1 cc
2 cc
2 cc
2 cc
2 cc
2 cc
2 cc
2 cc
具体原因,留给大家思考!