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

如何用fork()和pipe()创建链式子进程并实现用户输入累计?

实现方案

根据要求,我们需要构建Main → Child1 → Child2 → Child3的进程链,每个子进程(除最后一个)作为下一个子进程的父进程,通过管道传递累计输入字符串。以下是完整代码实现:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>

#define BUF_SIZE 100

int main() {
    printf("(Main started.)\n");

    // 管道1: Child1 → Main
    int fd1[2];
    if (pipe(fd1) == -1) {
        perror("pipe1 failed");
        return 1;
    }

    pid_t id1 = fork();
    if (id1 == -1) {
        perror("fork1 failed");
        return 1;
    }

    if (id1 == 0) {
        // Child1 进程
        printf("(Child 1 started)\n");
        close(fd1[0]); // Child1 只写管道1

        // 管道2: Child2 → Child1
        int fd2[2];
        if (pipe(fd2) == -1) {
            perror("pipe2 failed");
            return 1;
        }

        pid_t id2 = fork();
        if (id2 == -1) {
            perror("fork2 failed");
            return 1;
        }

        if (id2 == 0) {
            // Child2 进程
            printf("(Child 2 started)\n");
            close(fd2[0]); // Child2 只写管道2

            // 管道3: Child3 → Child2
            int fd3[2];
            if (pipe(fd3) == -1) {
                perror("pipe3 failed");
                return 1;
            }

            pid_t id3 = fork();
            if (id3 == -1) {
                perror("fork3 failed");
                return 1;
            }

            if (id3 == 0) {
                // Child3 进程(最后一个子进程)
                printf("(Child 3 started)\n");
                close(fd3[0]); // Child3 只写管道3

                char input;
                char buf[BUF_SIZE] = "";
                printf("(Child 3 input) So far: '%s'. Enter a string >>> ", buf);
                scanf("%c", &input);
                // 处理输入后的换行符
                while (getchar() != '\n');

                // 将输入字符转为字符串写入管道3
                buf[0] = input;
                buf[1] = '\0';
                write(fd3[1], buf, strlen(buf) + 1); // +1 包含终止符

                close(fd3[1]);
                return 0;
            } else {
                // Child2 父进程逻辑
                close(fd3[1]); // Child2 只读管道3

                char recv_buf[BUF_SIZE];
                read(fd3[0], recv_buf, BUF_SIZE); // 读取Child3的输入
                close(fd3[0]);

                wait(NULL); // 等待Child3结束

                char input;
                printf("(Child 2 input) So far: '%s'. Enter a string >>> ", recv_buf);
                scanf("%c", &input);
                while (getchar() != '\n');

                // 拼接字符串
                strncat(recv_buf, &input, 1);
                write(fd2[1], recv_buf, strlen(recv_buf) + 1); // 写入管道2给Child1

                close(fd2[1]);
                return 0;
            }
        } else {
            // Child1 父进程逻辑
            close(fd2[1]); // Child1 只读管道2

            char recv_buf[BUF_SIZE];
            read(fd2[0], recv_buf, BUF_SIZE); // 读取Child2的拼接结果
            close(fd2[0]);

            wait(NULL); // 等待Child2结束

            char input;
            printf("(Child 1 input) So far: '%s'. Enter a string >>> ", recv_buf);
            scanf("%c", &input);
            while (getchar() != '\n');

            // 拼接字符串
            strncat(recv_buf, &input, 1);
            write(fd1[1], recv_buf, strlen(recv_buf) + 1); // 写入管道1给Main

            close(fd1[1]);
            return 0;
        }
    } else {
        // Main 父进程逻辑
        close(fd1[1]); // Main 只读管道1

        char result[BUF_SIZE];
        read(fd1[0], result, BUF_SIZE); // 读取Child1的最终结果
        close(fd1[0]);

        wait(NULL); // 等待Child1结束

        printf("(Main) Result: '%s'\n", result);
        return 0;
    }
}

代码说明

  1. 进程链构建:通过嵌套的fork()调用,依次创建Child1、Child2、Child3,形成层级关系,完全符合"除最后一个子进程外,每个子进程作为下一个子进程的父进程"的要求。
  2. 管道通信:每个层级间创建独立管道,用于子进程向父进程传递累计字符串。每个进程仅保留管道的读写端之一,避免资源泄漏。
  3. 输入处理:使用scanf读取单个字符,并用循环清除输入缓冲区的换行符,避免后续输入被干扰。
  4. 字符串拼接:每个父进程读取子进程传递的字符串后,拼接自身输入的字符,再传递给上一层父进程,最终Main进程得到完整的累计结果。
  5. 进程等待:使用wait(NULL)等待子进程结束,避免产生僵尸进程。

运行测试

编译并运行代码:

gcc -o process_chain main.c
./process_chain

输出示例:

(Main started.)
(Child 1 started)
(Child 2 started)
(Child 3 started)
(Child 3 input) So far: ''. Enter a string >>> a
(Child 2 input) So far: 'a'. Enter a string >>> b
(Child 1 input) So far: 'ab'. Enter a string >>> c
(Main) Result: 'abc'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:54:54