MST

星途 面试题库

面试题:C语言Linux下waitpid函数的高级应用

在Linux系统中,使用C语言编写程序,利用waitpid函数实现父进程等待特定子进程的结束,同时处理可能出现的僵尸进程问题。要求阐述waitpid函数相较于wait函数的优势,以及如何根据不同的场景选择使用这两个函数。
12.8万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main() {
    pid_t child_pid, wpid;
    int status;

    // 创建子进程
    child_pid = fork();
    if (child_pid == -1) {
        perror("fork");
        return 1;
    } else if (child_pid == 0) {
        // 子进程
        printf("子进程: 我的PID是 %d\n", getpid());
        sleep(2); // 模拟子进程执行任务
        printf("子进程结束\n");
        exit(0);
    } else {
        // 父进程
        // 使用waitpid等待特定子进程
        wpid = waitpid(child_pid, &status, 0);
        if (wpid == -1) {
            perror("waitpid");
            return 1;
        }
        if (WIFEXITED(status)) {
            printf("父进程: 子进程 %d 正常结束,退出状态码: %d\n", wpid, WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
            printf("父进程: 子进程 %d 被信号 %d 终止\n", wpid, WTERMSIG(status));
        }
    }

    return 0;
}

waitpid函数相较于wait函数的优势

  1. 等待特定子进程wait 函数会等待任意一个子进程结束,而 waitpid 可以通过指定 pid 参数等待特定的子进程结束。例如,在一个程序创建了多个子进程的情况下,使用 waitpid 可以精准地等待某个子进程完成任务。
  2. 非阻塞等待waitpid 的第三个参数 options 可以设置为 WNOHANG,这样如果指定的子进程还没有结束,waitpid 会立即返回,而不会阻塞父进程。wait 函数只能阻塞等待子进程结束。这在需要父进程同时处理其他任务,又要关注子进程状态的场景下非常有用。
  3. 灵活性waitpid 提供了更多的控制选项,例如可以设置 WUNTRACED 选项,这样不仅等待子进程正常结束,还可以等待因信号而停止的子进程,这在调试子进程等场景下很有帮助。

根据不同场景选择使用这两个函数

  1. 简单场景:如果程序只创建了一个子进程,并且父进程只需要等待这个子进程结束,使用 wait 函数就足够了,因为代码会更简洁。例如简单的命令行工具,在执行某个外部命令时创建一个子进程,等待子进程执行完毕后继续父进程的其他操作。
  2. 复杂场景
    • 多子进程管理:当程序创建了多个子进程,并且需要分别处理每个子进程的结束状态,或者需要等待特定子进程完成时,应使用 waitpid 函数。例如一个服务器程序,为每个客户端请求创建一个子进程处理任务,服务器需要对每个子进程的结束状态进行记录和处理。
    • 并发处理:如果父进程需要在等待子进程的同时继续执行其他任务,应使用 waitpid 并设置 WNOHANG 选项进行非阻塞等待。例如在一个多媒体处理程序中,父进程在等待子进程完成视频编码的同时,还需要处理用户界面的交互操作。