链式多进程统计文件行/词/字符数 pipe传值累加异常问题求助
错误根源
- 子进程处理完当前文件逻辑后未调用
exit()主动退出,会继续执行后续循环代码,重复创建新进程、重复打印日志。 - 进程的地址空间相互独立,子进程对本地累加变量的修改无法同步到父进程,仅靠父进程本地累加无法拿到所有子进程的统计值。
- 原有
break逻辑仅让主进程拿到第一个子进程的统计值就终止循环,因此总和仅包含第一个文件的统计结果;删除break后所有进程都会继续执行fork逻辑,进程数指数级增长,因此会出现多次重复打印。
符合链式进程要求的修复代码
int send[3], get[3]; int fd[2]; int totLines = 0, totWords = 0, totChars = 0; int i; pid_t pid; // filenames为存储所有待统计文件名的数组 for (i = 0; i < n; i++) { pipe(fd); pid = fork(); if (pid < 0) { perror("fork"); exit(1); } else if (pid == 0) { // 处理当前第i个文件的统计 countFile(filenames[i], send); printf("PID: %d - PPID: %d - %s l=%d w=%d c=%d\n", getpid(), getppid(), filenames[i], send[0], send[1], send[2]); int curL = send[0], curW = send[1], curC = send[2]; int subTot[3] = {0}; close(fd[0]); // 非最后一个进程,需要创建下一级子进程获取后续统计总和 if (i < n - 1) { int sub_fd[2]; pipe(sub_fd); pid_t sub_pid = fork(); if (sub_pid < 0) { perror("sub fork"); exit(1); } else if (sub_pid == 0) { // 下一级子进程回到循环处理i+1个文件 close(sub_fd[1]); continue; } else { close(sub_fd[1]); read(sub_fd[0], subTot, sizeof(subTot)); close(sub_fd[0]); wait(NULL); } } // 累加自身统计值和后续子进程的统计总和,传给上级父进程 send[0] = curL + subTot[0]; send[1] = curW + subTot[1]; send[2] = curC + subTot[2]; write(fd[1], send, sizeof(send)); close(fd[1]); // 子进程任务完成,主动退出避免执行后续父进程逻辑 exit(0); } else { // 上级父进程读取当前子进程返回的累加总和 close(fd[1]); read(fd[0], get, sizeof(get)); totLines = get[0]; totWords = get[1]; totChars = get[2]; close(fd[0]); // 父进程无需再创建子进程,跳出循环 break; } } // 仅最顶层的主进程执行打印总和逻辑 if (pid != 0) { for (i = 0; i < n; i++) { wait(NULL); } printf("Total: l=%d w=%d c=%d\n", totLines, totWords, totChars); }
核心修改点
- 每个子进程完成统计、传递数据后主动调用
exit(0)退出,避免重复执行逻辑。 - 非最后一个子进程会创建下一级子进程,拿到后续所有文件的统计总和后,加上自身统计值再向上传递,最终主进程拿到的就是所有文件的统计总和。
- 仅最顶层的主进程会执行总和打印逻辑,避免重复打印。
内容的提问来源于stack exchange,提问作者Exec
相关产品推荐
相关产品推荐

