如何让父进程停止等待且不退出当前进程?
让子进程不退出时通知父进程结束等待的实现方法
要实现子进程不退出就通知父进程停止阻塞等待,核心是通过信号或进程间通信(IPC)机制打破父进程的等待逻辑。下面给出两种常用的实现方案:
方法一:使用自定义信号(最简单直接)
利用Linux的自定义信号(比如SIGUSR1),子进程发送信号唤醒父进程,父进程收到信号后退出等待逻辑,同时保留运行状态。
修改后的完整代码:
#include <signal.h> #include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> // 信号处理函数,空实现即可,仅用于触发唤醒 void sig_handler(int sig) {} int main() { // 注册SIGUSR1信号的处理函数 signal(SIGUSR1, sig_handler); pid_t p1 = fork(); if (p1) { printf("parent: %d\n", getpid()); int stat; pid_t wait_ret; while (1) { // 非阻塞检查子进程是否意外退出 wait_ret = waitpid(p1, &stat, WNOHANG); if (wait_ret == p1) { printf("child exited unexpectedly\n"); break; } else if (wait_ret == -1) { perror("waitpid error"); break; } // 阻塞等待信号到来 pause(); // 收到信号后停止等待,继续执行 printf("parent received signal, stop waiting\n"); break; } printf("parent continues running...\n"); // 后续可以继续监控子进程或执行其他逻辑 waitpid(p1, &stat, 0); printf("parent end\n"); } else { printf("child: %d\n", getpid()); printf("child parent: %d\n", getppid()); sleep(3); // 发送SIGUSR1信号给父进程,通知停止等待 kill(getppid(), SIGUSR1); sleep(3); printf("child end\n"); } return 0; }
关键逻辑说明
- 父进程提前注册
SIGUSR1信号的处理函数(空函数即可,只需要触发唤醒) - 父进程用
waitpid(WNOHANG)非阻塞检查子进程状态,避免子进程意外退出时父进程永久阻塞 - 子进程在需要通知的位置调用
kill(getppid(), SIGUSR1),向父进程发送信号,唤醒父进程的pause()阻塞
方法二:使用匿名管道(更可靠的IPC方式)
通过匿名管道实现进程间同步,父进程阻塞在管道读端,子进程写入数据后父进程立即停止等待,这种方式不会出现信号丢失的问题,可靠性更高。
修改后的完整代码:
#include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> int main() { int pipe_fd[2]; // 创建匿名管道 if (pipe(pipe_fd) == -1) { perror("pipe error"); exit(EXIT_FAILURE); } pid_t p1 = fork(); if (p1) { printf("parent: %d\n", getpid()); // 父进程关闭管道写端 close(pipe_fd[1]); char buf; // 阻塞读取管道,收到数据后停止等待 read(pipe_fd[0], &buf, 1); printf("parent received notification, stop waiting\n"); close(pipe_fd[0]); // 继续监控子进程状态 int stat; waitpid(p1, &stat, 0); printf("parent end\n"); } else { printf("child: %d\n", getpid()); printf("child parent: %d\n", getppid()); // 子进程关闭管道读端 close(pipe_fd[0]); sleep(3); // 向管道写入一个字节,通知父进程 write(pipe_fd[1], "x", 1); close(pipe_fd[1]); sleep(3); printf("child end\n"); } return 0; }
关键逻辑说明
- 父进程在
fork前创建管道,确保父子进程共享管道文件描述符 - 父进程关闭写端,阻塞在
read()调用上;子进程关闭读端,在需要通知时写入一个字节 - 父进程读到数据后立即退出等待,后续可以继续执行其他逻辑或监控子进程
内容的提问来源于stack exchange,提问作者Baruch
相关产品推荐
相关产品推荐

