MST

星途 面试题库

面试题:C语言Linux环境下复杂场景子进程等待超时处理

假设在一个Linux C程序中,需要创建多个子进程(例如5个子进程),每个子进程执行不同的任务且执行时间不确定。要求父进程对每个子进程的等待都设置不同的超时时间(分别为3秒、5秒、4秒、7秒、6秒)。当某个子进程超时时,父进程不仅要记录该子进程超时的信息,还要继续等待其他子进程完成,并汇总所有子进程的执行结果(正常结束或超时)。请详细说明实现方案并给出关键代码段。
31.2万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

实现方案

  1. 创建子进程:使用 fork() 函数创建5个子进程。
  2. 设置不同超时时间:为每个子进程设置不同的超时时间,可以通过一个数组来存储每个子进程对应的超时时间。
  3. 等待子进程并处理超时:在父进程中使用 waitpid() 结合 alarm()select()epoll() 等机制来实现带有超时的等待。
  4. 记录结果:父进程记录每个子进程是正常结束还是超时,并汇总结果。

关键代码段

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

#define CHILD_PROCESSES 5
// 定义每个子进程的超时时间
int timeout[CHILD_PROCESSES] = {3, 5, 4, 7, 6}; 
// 存储每个子进程的结果
int results[CHILD_PROCESSES]; 

void alarm_handler(int signum) {
    // 忽略SIGALRM信号,防止重复触发
    signal(SIGALRM, SIG_IGN); 
    // 这里可以记录超时信息,例如打印超时子进程的PID
    printf("Sub - process timed out.\n"); 
}

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) {
            // 子进程执行不同任务,这里简单模拟为随机休眠一段时间
            srand(time(NULL) ^ getpid());
            int sleep_time = rand() % 10;
            sleep(sleep_time);
            exit(sleep_time);
        }
    }

    for (int i = 0; i < CHILD_PROCESSES; i++) {
        signal(SIGALRM, alarm_handler);
        alarm(timeout[i]);
        pid_t wpid = waitpid(pids[i], &status, 0);
        alarm(0); // 取消闹钟

        if (wpid == -1) {
            perror("waitpid");
            results[i] = -1; // 记录等待错误
        } else if (WIFEXITED(status)) {
            results[i] = WEXITSTATUS(status); // 记录正常结束的返回值
        } else {
            results[i] = -2; // 记录异常结束
        }
    }

    // 汇总并打印所有子进程的执行结果
    for (int i = 0; i < CHILD_PROCESSES; i++) {
        if (results[i] >= 0) {
            printf("Child process %d ended normally with result: %d\n", i, results[i]);
        } else if (results[i] == -1) {
            printf("Child process %d wait error\n", i);
        } else {
            printf("Child process %d timed out or ended abnormally\n", i);
        }
    }

    return 0;
}
  1. 定义数组timeout 数组存储每个子进程的超时时间,results 数组存储每个子进程的执行结果。
  2. 子进程任务:子进程通过 srand(time(NULL) ^ getpid()) 随机生成一个休眠时间,模拟不同任务执行时间。
  3. 父进程等待:父进程使用 waitpid() 等待子进程,并通过 alarm() 设置超时时间,在超时信号处理函数 alarm_handler 中记录超时信息。
  4. 结果汇总:最后父进程遍历 results 数组,汇总并打印每个子进程的执行结果。