MST

星途 面试题库

面试题:C语言中处理子进程异常终止情况的状态分析

在Linux下用C语言编写代码,创建多个子进程,其中一个子进程模拟除零错误导致异常终止。父进程需要等待所有子进程结束,并能够准确分析出哪个子进程是因为异常终止的,以及异常的原因,写出实现思路和关键代码。同时说明waitpid()函数的使用场景和与wait()函数相比的优势。
21.6万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 创建子进程:使用fork()函数创建多个子进程。
  2. 模拟除零错误:在其中一个子进程中进行除零操作,触发异常。
  3. 父进程等待子进程结束:父进程使用waitpid()函数等待每个子进程结束,并获取子进程的退出状态。
  4. 分析异常原因:通过检查子进程的退出状态,判断是否是因为信号导致的异常终止,并确定异常原因。

关键代码

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

#define CHILD_PROCESSES 3

int main() {
    pid_t pids[CHILD_PROCESSES];
    int status;

    for (int i = 0; i < CHILD_PROCESSES; i++) {
        pids[i] = fork();
        if (pids[i] == -1) {
            perror("fork");
            return 1;
        } else if (pids[i] == 0) {
            // 子进程
            if (i == 1) {
                // 模拟除零错误
                int a = 1 / 0;
            }
            exit(i);
        }
    }

    // 父进程
    for (int i = 0; i < CHILD_PROCESSES; i++) {
        pid_t terminated_pid = waitpid(pids[i], &status, 0);
        if (terminated_pid == -1) {
            perror("waitpid");
            return 1;
        }

        if (WIFEXITED(status)) {
            printf("子进程 %d 正常退出,退出状态: %d\n", terminated_pid, WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
            printf("子进程 %d 异常终止,信号: %d\n", terminated_pid, WTERMSIG(status));
        }
    }

    return 0;
}

waitpid()函数的使用场景和优势

  1. 使用场景
    • 当需要等待特定子进程结束时,waitpid()函数可通过指定子进程的PID来等待。
    • 若要在等待子进程时设置非阻塞模式,以便在子进程未结束时继续执行其他任务,waitpid()函数可通过设置选项实现。
  2. 优势
    • 相比wait()函数,waitpid()可等待指定的子进程,而wait()只能等待任意一个子进程结束。
    • waitpid()提供了更灵活的等待方式,如非阻塞等待,通过设置options参数为WNOHANG可实现。若子进程未结束,waitpid()不会阻塞父进程,而是立即返回0,父进程可继续执行其他代码。而wait()函数会一直阻塞父进程,直到有子进程结束。