You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fork()和pipe()实现1-100有序输出的程序调试问题

问题分析与修复方案

我一眼就看出你的代码里几个关键问题,直接导致进程卡在printProc函数里,咱们一步步拆解:

核心问题1:管道读写端完全搞反了

管道创建后,fd[0]是读端,fd[1]是写端,但你的代码完全搞反了读写方向:

  • 初始同步时你写了write(fd[0], &start, sizeof(start));,这是往读端写数据,完全无效
  • 在printProc里又用read(fd[1], &proc, sizeof(proc));,从写端读数据,根本读不到任何内容,进程自然会一直阻塞在这里

核心问题2:初始同步逻辑错误

你想通过管道传递proc值来控制进程交替输出,但初始写入的start=0没有正确进入管道,子进程(负责输出奇数,procNumber=0)根本读不到初始的控制信号,没法启动输出流程。

其他小问题

  • 多个进程同时用a+模式打开文件,虽然POSIX下追加写入是原子操作,但缺少缓存刷新,可能导致内容写入延迟
  • 没有关闭管道的未使用端,可能导致进程结束时无法正确释放资源,甚至意外阻塞

修复后的完整代码

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>

int fd[2];
int printProc(int startNumber, int procNumber);

int main() {
    pid_t childpid;
    // 增加管道创建的错误检查
    if (pipe(fd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    int start = 0;
    // 往管道写端(fd[1])写入初始控制值
    write(fd[1], &start, sizeof(start));

    if ((childpid = fork()) == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (childpid == 0) {
        printf("run child (odd numbers)\n");
        // 子进程不需要写管道,关闭写端
        close(fd[1]);
        printProc(1, 0);
        close(fd[0]);
    } else {
        printf("run parent (even numbers)\n");
        // 父进程不需要读管道,关闭读端
        close(fd[0]);
        printProc(2, 1);
        close(fd[1]);
    }
    return 0;
}

int printProc(int startNumber, int procNumber) {
    FILE *f = fopen("output.txt", "a");
    if (!f) {
        perror("fopen");
        return -1;
    }

    int num = startNumber;
    int proc;
    while (num <= 100) {
        // 从管道读端(fd[0])读取控制值
        read(fd[0], &proc, sizeof(proc));
        if (proc == procNumber) {
            fprintf(f, "%d ", num);
            fflush(f); // 立即刷新缓存,确保内容实时写入文件
            printf("printed %d\n", num); // 控制台输出便于调试
            num += 2;
            // 切换控制进程,写入管道写端(fd[1])
            proc = (proc + 1) % 2;
            write(fd[1], &proc, sizeof(proc));
        }
    }

    fclose(f);
    return 0;
}

修复细节说明

  1. 修正管道读写端:所有write操作使用fd[1](写端),read操作使用fd[0](读端),符合管道的标准用法
  2. 关闭未使用的管道端:子进程关闭写端、父进程关闭读端,避免进程结束时因管道未完全关闭导致的阻塞
  3. 文件操作优化:用a模式代替a+(仅需追加写入),每次写入后调用fflush确保内容立即落盘,避免多进程缓存导致的顺序混乱
  4. 增强错误处理:添加了pipe和fopen的错误检查,让程序更健壮

现在运行这个程序,output.txt里会按顺序输出1到100的所有数字,两个进程会交替执行,不会再卡住啦!

内容的提问来源于stack exchange,提问作者Claus Stolz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:52:20