僵尸进程(Zombie Process)是指在操作系统中已经完成了执行,但其父进程尚未调用wait()
或waitpid()
来获取其终止状态的子进程。当一个进程结束时,操作系统会保留该进程的一些基本信息,包括进程ID(PID)、退出状态等,以供父进程查询。而如果父进程没有主动调用上述函数来检索该进程的状态,那么这个进程的信息就会一直存在于操作系统的进程表中,成为僵尸进程。
如下是一个产生僵尸进程的代码
void fork7() {
if (fork() == 0) {
/* Child */
printf("Terminating Child, PID = %d\n", getpid());
exit(0);
} else {
printf("Running Parent, PID = %d\n", getpid());
while (1); /* Infinite loop */
}
}
其中子进程已经完成执行,但是进程表中仍然存在子进程的信息。,并显示为defunct状态,即zombie进程。
wait()
和waitpid()
是用于在父进程中等待子进程终止并获取其终止状态的系统调用函数。
这两个函数的作用包括:
-
等待子进程的终止:父进程可以使用
wait()
或waitpid()
函数来暂停自己的执行,等待子进程结束。在子进程终止之前,父进程会一直阻塞在这个调用上。 -
获取子进程的终止状态:当子进程终止时,操作系统会将子进程的退出状态传递给父进程。父进程通过调用
wait()
或waitpid()
来获取子进程的终止状态,并可以根据该状态进行后续处理。终止状态可以包含子进程的退出码、终止原因等信息。
pid_t wait(int* status);
status
参数用于保存子进程的终止状态。通过检查status
变量的值,父进程可以了解子进程的终止情况。wait()
函数返回已终止的子进程的PID,若出错则返回-1。
pid_t waitpid(pid_t pid, int* status, int options);
pid
参数用于指定等待的子进程ID。当指定为-1时,表示等待任意一个子进程终止。status
参数用于保存子进程的终止状态。options
参数用于设置额外的选项,例如WNOHANG表示非阻塞等待。
wait()
和waitpid()
函数的返回值可以提供一些信息:
- 返回一个大于0的值表示已终止的子进程的PID。
- 返回0表示使用了WNOHANG选项,且当前没有已终止的子进程。
- 返回-1表示调用出错,可能是由于权限问题或者无效的参数。
示例
void fork9() {
int child_status;
if (fork() == 0) {
printf("HC: hello from child\n");
} else {
printf("HP: hello from parent\n");
wait(&child_status);
printf("CT: child has terminated\n");
}
printf("Bye\n");
}
父进程通过使用wait函数来暂停自己的执行,等待子进程结束,在子进程终止之前,父进程会一直阻塞在这个调用上