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

如何用C编写通过管道、fork、exec控制B、C进程完成计算的程序A

C语言程序A实现方案

实现逻辑说明

  • 总共需要创建4个管道:分别对应B的输入(A写、B读)、B的输出(B写、A读)、C的输入(A写、C读)、C的输出(C写、A读)
  • 两次调用fork()创建子进程,子进程内通过dup2()将标准输入、标准输出重定向到对应管道,之后调用exec()启动已开发完成的B、C程序
  • 父进程关闭不需要的管道端,生成初始随机数后按要求循环100次迭代,每次数据传输后间隔1秒,同时按指定格式打印进程间通信日志

完整代码

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

int main() {
    // 管道定义:fd[0]读端,fd[1]写端
    int b_in[2], b_out[2]; // B的输入、输出管道
    int c_in[2], c_out[2]; // C的输入、输出管道

    // 创建所有管道
    if (pipe(b_in) < 0 || pipe(b_out) < 0 || pipe(c_in) < 0 || pipe(c_out) < 0) {
        perror("创建管道失败");
        exit(1);
    }

    // 启动子进程B
    pid_t pid_b = fork();
    if (pid_b < 0) {
        perror("fork B失败");
        exit(1);
    } else if (pid_b == 0) {
        // 子进程B:重定向标准输入到b_in读端,标准输出到b_out写端
        close(b_in[1]);
        close(b_out[0]);
        dup2(b_in[0], STDIN_FILENO);
        dup2(b_out[1], STDOUT_FILENO);
        // 关闭无关管道
        close(c_in[0]); close(c_in[1]);
        close(c_out[0]); close(c_out[1]);
        // 执行B程序,假设B的可执行文件名为./b
        execlp("./b", "./b", NULL);
        perror("exec B失败");
        exit(1);
    }

    // 启动子进程C
    pid_t pid_c = fork();
    if (pid_c < 0) {
        perror("fork C失败");
        exit(1);
    } else if (pid_c == 0) {
        // 子进程C:重定向标准输入到c_in读端,标准输出到c_out写端
        close(c_in[1]);
        close(c_out[0]);
        dup2(c_in[0], STDIN_FILENO);
        dup2(c_out[1], STDOUT_FILENO);
        // 关闭无关管道
        close(b_in[0]); close(b_in[1]);
        close(b_out[0]); close(b_out[1]);
        // 执行C程序,假设C的可执行文件名为./c
        execlp("./c", "./c", NULL);
        perror("exec C失败");
        exit(1);
    }

    // 父进程A:关闭不需要的管道端
    close(b_in[0]); close(b_out[1]);
    close(c_in[0]); close(c_out[1]);

    // 初始化随机数
    srand(time(NULL));
    int current = rand() % 100; // 初始随机数取0-99之间,可按需调整范围

    // 循环迭代100次
    for (int i = 1; i <= 100; i++) {
        char buf[64] = {0};
        // 1. 给B发数据
        printf("%03d. A -> B %d\n", i, current);
        sprintf(buf, "%d\n", current);
        write(b_in[1], buf, strlen(buf));
        sleep(1);

        // 2. 读B的返回
        memset(buf, 0, sizeof(buf));
        read(b_out[0], buf, sizeof(buf));
        int res_b = atoi(buf);
        printf("B -> A %d\n", res_b);
        sleep(1);

        // 3. 给C发数据
        printf("A -> C %d\n", res_b);
        sprintf(buf, "%d\n", res_b);
        write(c_in[1], buf, strlen(buf));
        sleep(1);

        // 4. 读C的返回
        memset(buf, 0, sizeof(buf));
        read(c_out[0], buf, sizeof(buf));
        int res_c = atoi(buf);
        printf("C -> A %d\n", res_c);
        sleep(1);

        // 更新current为下一次迭代的输入
        current = res_c;
    }

    // 关闭剩余管道,等待子进程退出
    close(b_in[1]); close(b_out[0]);
    close(c_in[1]); close(c_out[0]);
    waitpid(pid_b, NULL, 0);
    waitpid(pid_c, NULL, 0);

    return 0;
}

注意事项

  • 编译运行前需要确保B、C程序的可执行文件命名为./b和./c,和代码中execlp的路径保持一致,也可以自行修改为B、C的实际存储路径
  • 如果B、C的输出不带换行,可以在代码中调整读逻辑,按固定字节数读取即可
  • 随机数的取值范围可以通过修改rand() % 100的参数按需调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:06:01