面试题答案
一键面试- 关键数据结构:
- 信号处理相关结构体:
struct sigaction
用于设置信号处理函数。例如:
struct sigaction sa;
- 进程控制块相关:在
waitpid
函数中会涉及到用于获取子进程状态的int status
变量,用于检查子进程退出原因等。
int status;
- 信号处理相关结构体:
- 函数调用逻辑:
- 信号处理函数注册:
- 使用
sigemptyset
初始化信号集,使用sigaction
注册信号处理函数,处理子进程退出信号(如SIGCHLD
)。
void handle_child_exit(int signum) { pid_t pid; while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { // 子进程异常退出,重新创建子进程 if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { // 重新fork子进程 pid_t new_pid = fork(); if (new_pid == 0) { // 子进程逻辑,恢复原有工作状态,例如重新加载业务模块等 // 假设这里有一个函数reload_work()用于恢复工作状态 reload_work(); exit(0); } } } } int main() { struct sigaction sa; sa.sa_handler = handle_child_exit; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGCHLD, &sa, NULL); // 主进程prefork创建子进程逻辑 for (int i = 0; i < num_child_processes; i++) { pid_t pid = fork(); if (pid == 0) { // 子进程工作逻辑 do_child_work(); exit(0); } } // 主进程其他逻辑 while (1) { // 主进程可以做其他事情 sleep(1); } return 0; }
- 使用
waitpid
函数:在信号处理函数中使用waitpid
等待子进程退出,并且通过WIFEXITED
、WEXITSTATUS
等宏判断子进程是否正常退出以及退出状态。fork
函数:在子进程异常退出后,在信号处理函数中重新使用fork
创建新的子进程,新子进程通过调用相应的函数(如上述reload_work
函数模拟)来恢复原有工作状态。
- 信号处理函数注册:
以上代码通过信号处理机制,在子进程异常退出时及时捕获并重新创建子进程恢复工作状态。实际应用中,reload_work
和do_child_work
函数需要根据具体业务逻辑进行实现。