异常处理策略
- 子进程非正常退出:使用
waitpid
函数等待子进程,并通过WIFEXITED
和WEXITSTATUS
宏检查子进程是否正常退出。如果子进程非正常退出,可以记录日志并进行相应处理。
- 父进程接收到信号:注册信号处理函数,在信号处理函数中可以记录日志或者进行必要的清理工作,同时确保信号处理函数的可重入性。
资源管理思路
- 文件描述符:在子进程创建前关闭不必要的文件描述符,避免子进程继承。在程序结束时,关闭所有打开的文件描述符。
- 内存:动态分配的内存要及时释放,避免内存泄漏。
代码实现
#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;
}