如何使用fork实现进程并发?让子进程在父进程退出后运行
实现子进程在父进程退出后执行操作的方法
首先得提一句,你代码里的变量名有点容易混淆——pid_t parent = fork();这里,fork返回0的时候是子进程,返回非0值是父进程拿到的子进程PID,把变量名改成pid_t child_pid = fork();会更清晰,避免后续理解出错。
回到你的问题:确实有办法让子进程等父进程退出后再执行打印,下面给你两种实用的方案:
方案一:用waitpid主动等待父进程退出
子进程可以通过getppid()获取父进程的PID,然后调用waitpid()等待父进程终止。需要注意处理父进程已经提前退出的情况(这时候getppid()会返回1,也就是init/systemd进程的PID),代码示例如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <unistd.h> #include <errno.h> int main(int argc, char **argv) { FILE *file; file = fopen(argv[1], "r"); if (!file) { // 别忘了加文件打开失败的判断 perror("fopen failed"); exit(1); } char buf[600]; pid_t first_child = fork(); if(first_child == 0) { while (fgets(buf, sizeof(buf), file)) { pid_t grand_child = fork(); if(grand_child == 0) { // 等待父进程(first_child)退出 pid_t parent_pid = getppid(); int status; // 循环处理waitpid可能的错误 while (waitpid(parent_pid, &status, 0) == -1) { if (errno == ECHILD) { // 父进程已经退出,直接执行后续逻辑 break; } } printf("%s\n", buf); fclose(file); // 子进程也要关闭文件句柄 return(0); } } fclose(file); return(0); } wait(NULL); return(0); }
这种方法的优势是兼容性好,几乎所有类Unix系统都支持,缺点是需要处理错误情况,代码稍显繁琐。
方案二:用prctl让父进程退出时通知子进程
如果是在Linux系统下,可以用prctl()系统调用设置一个“父进程退出信号”——当父进程终止时,内核会给子进程发送指定的信号,子进程等待这个信号后再执行打印。代码示例:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <unistd.h> #include <sys/prctl.h> #include <signal.h> int main(int argc, char **argv) { FILE *file; file = fopen(argv[1], "r"); if (!file) { perror("fopen failed"); exit(1); } char buf[600]; pid_t first_child = fork(); if(first_child == 0) { while (fgets(buf, sizeof(buf), file)) { pid_t grand_child = fork(); if(grand_child == 0) { // 设置父进程退出时发送SIGUSR1信号 prctl(PR_SET_PDEATHSIG, SIGUSR1); // 暂停等待信号 pause(); printf("%s\n", buf); fclose(file); return(0); } } fclose(file); return(0); } wait(NULL); return(0); }
这种方式代码更简洁,但要注意prctl()是Linux特有的接口,在BSD、macOS等系统上无法使用。
另外补充一点:你原代码里主进程只wait(NULL)了一次,也就是只等待第一个子进程退出,但第一个子进程fork出来的那些孙进程会变成孤儿进程,被init/systemd收养。如果需要等待所有子进程退出,你可能需要在第一个子进程里循环调用wait()或者waitpid()。
内容的提问来源于stack exchange,提问作者user9314692
相关产品推荐
相关产品推荐

