在Linux系统中,创建新进程涉及到两个系统调用API:分别是fork()和exec().
首先,在当前进程中,调用fork()复制出自身的一个拷贝,此时主要涉及到内核中与进程上下文相关的数据复制操作,而用户代码和数据则采用写时复制技术共享同一份资源。当一个进程复制后,原进程称为父进程,新进程则称为子进程.
然后,在子进程用一个新进程镜像替代自身,即从磁盘中装入一个新程序,并作为当前的子进程运行.这可通过调用exec()函数簇中的一个函数来实现,exec()函数簇中的所有函数都完成同样的工作,所不同的是作为命令行传递到新程序中的参数的组织形式.
/* forkexec.c */
#include <unistd.h>
int main(int argc, char *argv[])
{
int pid;
int childpid;
int status;
if ((pid = fork()) == 0) {
printf("Child: pid = %d parentpid = %d\n", getpid(), getppid());
execlp("./showargs", "first", "second", "third", NULL);
printf("Child: This should never print\n");
}
printf("Parent: pid = %d childpid = %d\n",getpid(), pid);
childpid = wait(&status);
printf("Parent: child %d died\n", childpid);
return 0;
}
其实,所有的进程都可以使用fork和exec函数调用来启动另一个新进程,实际上linux的所有进程都是以这种方式启动的,在系统启动以后,系统进程init开始运行,它完成了启动其它进程的任务,init进程的进程ID号总为1。