fork函数
父进程通过调用fork函数来创建一个子进程
- 新创建的子进程几乎但不完全与父进程相同,子进程与父进程最大的区别在于他们有不同的PID。
- fork函数调用一次,返回两次,在父进程中,fork返回子进程的PID,在子进程中,fork返回0.
- 并发执行,子进程与父进程是并发执行的独立程序。内核能够以任意方式交替执行它们的逻辑控制流中的指令。(在我们的系统上运行这个程序时,父进程先完成它的printf语句,然后是子进程。然而,在另一个系统上可能正好相反)
每个进程都会有一个唯一的正数(非零)进程ID/PID.getpid函数返回调用进程的PID,getppid函数返回父进程的PID(调用调用进程的进程)。
下面对不同的fork函数代码进行分析:
fork0,最简单的fork函数,代码如下:
void fork0()
{
if (fork() == 0) {
printf("Hello from child\n");
}
else {
printf("Hello from parent\n");
}
}
运行结果如下:
fork1
void fork1()
{
int x = 1;
pid_t pid = fork();
if (pid == 0) {
printf("Child has x = %d\n", ++x);
}
else {
printf("Parent has x = %d\n", --x);
}
printf("Bye from process %d with x = %d\n", getpid(), x);
}
运行结果:
子进程的PID=73613,而父进程的PID=73612.父进程先完成printf。
fork2
void fork2()
{
printf("L0\n");
fork();
printf("L1\n");
fork();
printf("Bye\n");
}
流程图如下:
运行结果如下:
fork3
void fork3()
{
printf("L0\n");
fork();
printf("L1\n");
fork();
printf("L2\n");
fork();
printf("Bye\n");
}
流程图如下:
运行结果如下:
fork4
void fork4()
{
printf("L0\n");
if (fork() != 0) {
printf("L1\n");
if (fork() != 0) {
printf("L2\n");
}
}
printf("Bye\n");
}
流程图如下:
运行结果如下:
fork5
void fork5()
{
printf("L0\n");
if (fork() == 0) {
printf("L1\n");
if (fork() == 0) {
printf("L2\n");
}
}
printf("Bye\n");
}
流程图如下:
运行结果如下:
主函数代码如下:
int main(int argc, char *argv[])
{
int option = 0;
if (argc > 1)
option = atoi(argv[1]);
switch(option) {
case 0: fork0();
break;
case 1: fork1();
break;
case 2: fork2();
break;
case 3: fork3();
break;
case 4: fork4();
break;
case 5: fork5();
break;
default:
printf("Unknown option %d\n", option);
break;
}
return 0;
}
共有18个fork相关的函数,由于本人能力有限,只分析了较简单的几个fork,仅供参考。