父进程结束把子进程带走
当然可以!下面是一个使用 C 语言编写的示例,演示了如何通过信号处理确保在主动终止程序时,子进程和父进程都能正确地结束。示例代码中,父进程和子进程都进行一些工作,并且父进程会捕获终止信号来确保子进程在程序终止时能够正确结束。
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
pid_t child_pid = -1; // 保存子进程的 PID
void handle_signal(int sig) {
// 当接收到终止信号时,处理子进程
if (child_pid > 0) {
printf("Parent received signal %d, terminating child process...\n", sig);
kill(child_pid, SIGTERM); // 发送信号终止子进程
waitpid(child_pid, NULL, 0); // 等待子进程结束
}
printf("Parent process terminating...\n");
exit(EXIT_SUCCESS); // 退出父进程
}
int main() {
int pipefd[2];
pid_t pid;
// 设置信号处理函数
struct sigaction sa;
sa.sa_handler = handle_signal;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL); // 捕获 Ctrl+C
sigaction(SIGTERM, &sa, NULL); // 捕获 TERM 信号
// 创建管道
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
// 创建子进程
if ((pid = fork()) == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) { // 子进程
child_pid = getpid(); // 记录子进程的 PID
close(pipefd[1]); // 关闭写端
// 子进程模拟工作
printf("Child process (PID %d) is working...\n", child_pid);
sleep(10);
close(pipefd[0]); // 关闭读端
printf("Child process (PID %d) is done.\n", child_pid);
exit(EXIT_SUCCESS);
} else { // 父进程
close(pipefd[0]); // 关闭读端
// 父进程模拟工作
printf("Parent process (PID %d) is working...\n", getpid());
sleep(10);
close(pipefd[1]); // 关闭写端
printf("Parent process (PID %d) is waiting for child to terminate...\n", getpid());
waitpid(pid, NULL, 0); // 等待子进程结束
printf("Parent process (PID %d) done.\n", getpid());
}
return 0;
}
解释
-
信号处理程序:
handle_signal
函数用于处理信号。当父进程接收到SIGINT
或SIGTERM
信号时,它会终止子进程并等待子进程结束。
-
信号处理配置:
- 使用
sigaction
配置信号处理程序,确保当程序接收到SIGINT
或SIGTERM
时,会调用handle_signal
函数。
- 使用
-
进程创建和管道:
- 父进程创建一个管道,然后使用
fork
创建一个子进程。 - 子进程模拟一些工作,然后退出。父进程也进行一些工作,然后等待子进程结束。
- 父进程创建一个管道,然后使用
-
清理工作:
- 父进程在退出前调用
waitpid
等待子进程结束,确保子进程被正确处理。
- 父进程在退出前调用
使用这种方式,可以确保在程序终止时,子进程能被正确终止,父进程也会在所有子进程完成后正确退出。