实现方案
- 创建子进程:使用
fork()
函数创建5个子进程。
- 设置不同超时时间:为每个子进程设置不同的超时时间,可以通过一个数组来存储每个子进程对应的超时时间。
- 等待子进程并处理超时:在父进程中使用
waitpid()
结合 alarm()
或 select()
、epoll()
等机制来实现带有超时的等待。
- 记录结果:父进程记录每个子进程是正常结束还是超时,并汇总结果。
关键代码段
#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;
}
- 定义数组:
timeout
数组存储每个子进程的超时时间,results
数组存储每个子进程的执行结果。
- 子进程任务:子进程通过
srand(time(NULL) ^ getpid())
随机生成一个休眠时间,模拟不同任务执行时间。
- 父进程等待:父进程使用
waitpid()
等待子进程,并通过 alarm()
设置超时时间,在超时信号处理函数 alarm_handler
中记录超时信息。
- 结果汇总:最后父进程遍历
results
数组,汇总并打印每个子进程的执行结果。