如何用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; } }
代码说明
- 进程链构建:通过嵌套的
fork()调用,依次创建Child1、Child2、Child3,形成层级关系,完全符合"除最后一个子进程外,每个子进程作为下一个子进程的父进程"的要求。 - 管道通信:每个层级间创建独立管道,用于子进程向父进程传递累计字符串。每个进程仅保留管道的读写端之一,避免资源泄漏。
- 输入处理:使用
scanf读取单个字符,并用循环清除输入缓冲区的换行符,避免后续输入被干扰。 - 字符串拼接:每个父进程读取子进程传递的字符串后,拼接自身输入的字符,再传递给上一层父进程,最终Main进程得到完整的累计结果。
- 进程等待:使用
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
相关产品推荐
相关产品推荐

