MST

星途 面试题库

面试题:C语言处理等待指定子进程时的异常情况与资源管理

在Linux环境下,用C语言编写程序实现等待指定子进程。考虑到可能出现的异常情况,如子进程意外终止(非正常退出)、父进程在等待过程中接收到信号等。要求程序不仅能正确处理这些异常,还要合理管理系统资源(如文件描述符、内存等),防止资源泄漏。阐述异常处理策略和资源管理思路,并给出完整且健壮的代码实现。
18.6万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

异常处理策略

  1. 子进程非正常退出:使用waitpid函数等待子进程,并通过WIFEXITEDWEXITSTATUS宏检查子进程是否正常退出。如果子进程非正常退出,可以记录日志并进行相应处理。
  2. 父进程接收到信号:注册信号处理函数,在信号处理函数中可以记录日志或者进行必要的清理工作,同时确保信号处理函数的可重入性。

资源管理思路

  1. 文件描述符:在子进程创建前关闭不必要的文件描述符,避免子进程继承。在程序结束时,关闭所有打开的文件描述符。
  2. 内存:动态分配的内存要及时释放,避免内存泄漏。

代码实现

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

// 信号处理函数
void sig_handler(int signum) {
    printf("父进程接收到信号: %d\n", signum);
    // 可以在这里进行日志记录或其他清理工作
}

int main() {
    pid_t pid;
    int status;

    // 注册信号处理函数
    signal(SIGINT, sig_handler);
    signal(SIGTERM, sig_handler);

    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    } else if (pid == 0) {
        // 子进程
        // 关闭不必要的文件描述符
        close(0); close(1); close(2);

        // 子进程执行的代码
        printf("子进程开始执行\n");
        // 模拟子进程正常退出
        // exit(EXIT_SUCCESS);
        // 模拟子进程异常退出
        abort(); 
    } else {
        // 父进程
        pid_t wpid = waitpid(pid, &status, 0);
        if (wpid == -1) {
            perror("waitpid");
            exit(EXIT_FAILURE);
        } else if (WIFEXITED(status)) {
            printf("子进程正常退出,退出状态码: %d\n", WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
            printf("子进程被信号终止,信号编号: %d\n", WTERMSIG(status));
        }
    }

    return 0;
}