switch(new_pid) { case -1: /* Error */ break; case 0: /* We are child */ break; default: /* We are parent */ break;
}
测试代码:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t pid;
char *message;
int n;
printf("fork program starting\n");
pid = fork();
switch(pid)
{
case -1:
perror("fork failed");
exit(1);
case 0:
message = "This is the child";
n = 5;
break;
default:
message = "This is the parent";
n = 3;
break;
}
for(; n > 0; n--) {
puts(message);
sleep(1);
}
exit(0);
}
一般情况下的运行及输出:
beyes@linux-beyes:~/C/call/fork> ./fork2.exe
fork program starting
This is the parent
This is the child
This is the parent
This is the child
This is the parent
This is the child
This is the child
beyes@linux-beyes:~/C/call/fork> This is the child
多次尝试运行次程序也会出现不同的输出结果:
beyes@linux-beyes:~/C/call/fork> ./fork2.exe
fork program starting
This is the parent
This is the child
This is the parent
This is the child
This is the child
This is the parent
This is the child
beyes@linux-beyes:~/C/call/fork> This is the child
说明:
不同的输出结果是因为系统调度对进程调度的原因。分析第一个输出的流程:首先执行 fork() 后创建了一个新的进程,但此时由于系统的调度原因,当前进程还是处于父进程空间中,所以输出“This is the parent“;接着执行了 sleep() 函数后,父进程睡眠,系统调度子进程运行,然后子进程输出“This is the child”,此后交替反复。如上面所说,子进程复制了父进程的上下文,所以父进程有父进程的 n 值(输出“This is the parent”3次),子进程也有子进程的 n 值( 输出"This is the child" 5次)。 Tip:
由于 fork() 完整地拷贝了父进程的整个地址空间,因此执行速度是比较慢的。为了加快 fork() 的执行速度,有些 UNIX 系统设计者创建了 vfork() 。vfork() 也能创建新进程,但它不产生父进程的副本。它是通过允许父子进程可访问相同物理空间内存从而伪装了对进程地址空间的真实拷贝,当子进程需要改变内存中的数据时才拷贝父进程。这就是著名的“写操作时拷贝“( copy-on-wirte)技术。