考虑到 fork 的返回值,现在该代码可以检查确定它是父进程还是子进程,并进行相应的操作。清单 3 显示了一个基于 fork 的结果来打印不同输出的程序。
清单 3. 更完整的 fork 用法示例
sunbox$ cat fork2.c
#include <unistd.h>
#include <stdio.h>
int main (void) {
pid_t p;
printf("Original program, pid=%dn", getpid());
p = fork();
if (p == 0) {
printf("In child process, pid=%d, ppid=%dn",
getpid(), getppid());
} else {
printf("In parent, pid=%d, fork returned=%dn",
getpid(), p);
}
}
sunbox$ gcc fork2.c -o fork2
sunbox$ ./fork2
Original program, pid=767
In child process, pid=768, ppid=767
In parent, pid=767, fork returned=768
清单 3 在每个步骤打印出 PID,并且该代码检查从 fork 返回的值来确定哪个进程是父进程,哪个进程是子进程。对所打印的 PID 进行比较,可以看到原始进程是父进程 (PID 767),并且子进程 (PID 768) 知道其父进程是谁。请注意子进程如何通过 getppid 来知道其父进程以及父进程如何使用 fork 来定位其子进程。
现在您已经了解了复制某个进程的方法,下面让我们研究如何运行一个不同的进程。fork 只是进程机制中的一半。exec 系列系统调用运行实际的程序。
使用 exec 系列系统调用
exec 的工作是将当前进程替换为一个新进程。请注意“替换这个措词的含义。在您调用 exec 以后,当前进程就消失了,新进程就启动了。如果希望创建一个单独的进程,您必须首先运行 fork,然后在子进程中执行 (exec) 新的二进制文件。清单 4 显示了这样一种情况。
标签: