循环调用fork()创建子进程后程序挂起的问题求助
问题分析与修复
核心问题
你的代码中子进程分支(case 0)缺少退出逻辑:
- 当
execlp执行成功时,子进程的代码会被sighandler完全替换,不会执行后续代码,这部分是正常的。 - 但如果
execlp执行失败(比如./sighandler不存在、权限不足、参数错误等),子进程会继续执行default分支的代码——也就是调用wait(&stat)。此时子进程没有创建任何子进程,wait会永久阻塞;同时父进程也在wait这个子进程,最终导致双向阻塞,程序挂起。
另外,原代码逻辑是创建一个子进程就立刻等待它退出,会变成串行执行5个子进程,虽然能完成功能,但如果想并行创建子进程再统一等待,可调整逻辑,但当前挂起问题的核心还是子进程分支的退出处理。
修复后的代码
#include <sys/wait.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { int stat; pid_t pd; for (int i = 0; i < 5; i++) { switch (pd = fork()) { case -1: perror("fork error!"); exit(1); case 0: // 执行execlp,失败则直接退出子进程 execlp("./sighandler", "./sighandler", argv[1], argv[2], (char *)NULL); // 走到这里说明execlp失败,打印错误并退出 perror("execlp failed"); exit(EXIT_FAILURE); default: // 等待当前子进程退出 if (wait(&stat) == -1) { perror("wait error!"); exit(2); } printf("PID = %d | Exit Status = %d\n", pd, WEXITSTATUS(stat)); } } return 0; }
关键修改点
- 在
case 0分支的execlp之后添加错误处理:execlp只有执行失败时才会返回,所以一旦走到这行代码之后,直接打印错误并调用exit终止子进程,避免子进程进入default分支执行wait。
- 优化打印信息的可读性,明确标注退出状态的含义。
可选优化:并行创建子进程后统一等待
如果希望5个子进程并行执行,而非串行等待,可先批量创建所有子进程,再循环等待全部退出,示例代码如下:
#include <sys/wait.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { int stat; pid_t pd; // 批量创建子进程 for (int i = 0; i < 5; i++) { switch (pd = fork()) { case -1: perror("fork error!"); exit(1); case 0: execlp("./sighandler", "./sighandler", argv[1], argv[2], (char *)NULL); perror("execlp failed"); exit(EXIT_FAILURE); default: printf("Created child PID: %d\n", pd); break; } } // 统一等待所有子进程退出 while ((pd = wait(&stat)) != -1) { printf("PID = %d | Exit Status = %d\n", pd, WEXITSTATUS(stat)); } return 0; }
内容的提问来源于stack exchange,提问作者fdnull
相关产品推荐
相关产品推荐

