面试题答案
一键面试在Linux C语言的prefork模型中,可使用wait
系列系统调用来监控已创建子进程的状态。
-
wait
函数:- 函数原型:
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
- 参数:
status
是一个指向整数的指针,用于存储子进程退出时的状态信息。如果不关心子进程的退出状态,可以传入NULL
。 - 功能:父进程调用
wait
函数会阻塞,直到任意一个子进程结束,然后wait
返回已结束子进程的进程ID,并通过status
参数获取子进程的退出状态。
- 函数原型:
-
waitpid
函数:- 函数原型:
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
- 参数:
pid
:指定等待哪个子进程。pid > 0
时,等待进程ID为pid
的子进程;pid = -1
时,等待任意子进程,功能类似wait
;pid = 0
时,等待同组ID的任意子进程;pid < -1
时,等待进程组ID等于pid
绝对值的任意子进程。status
:和wait
函数中的status
类似,用于获取子进程的退出状态。options
:可设置为0
,也可使用WNOHANG
等选项。WNOHANG
表示如果没有子进程退出,waitpid
不阻塞,立即返回。
- 函数原型:
例如:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t pid;
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid == 0) {
// 子进程
printf("Child process is running, pid: %d\n", getpid());
sleep(2);
exit(EXIT_SUCCESS);
} else {
// 父进程
int status;
pid_t wpid = waitpid(pid, &status, 0);
if (wpid == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
if (WIFEXITED(status)) {
printf("Child process %d exited normally, exit status: %d\n", wpid, WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("Child process %d was terminated by signal %d\n", wpid, WTERMSIG(status));
}
}
return 0;
}
在上述代码中,父进程使用waitpid
等待特定子进程结束,并通过status
获取子进程的退出状态,判断子进程是正常退出还是被信号终止。