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

两个C程序间管道通信无输出问题求解

问题原因与解决方案

你的程序陷入死锁,核心原因是管道写端未及时关闭,导致子进程的read调用一直阻塞等待更多数据,同时父进程在等待子进程返回结果,双方互相卡住。

具体问题点

  1. 父进程发送完所有数据后,没有关闭pipe_to_loop[1](管道写端)。子进程调用read(0, str1, sizeof(str1))尝试读取100字节,但父进程只发送了16字节(两个带终止符的字符串+一个int),且写端仍处于打开状态,子进程会一直等待更多数据,无法继续执行后续逻辑。
  2. 子进程的read调用未处理返回值,无法判断数据是否读取完毕或遇到EOF。

修改后的代码

nicecmp.c(父进程)

核心修改:发送完数据后立即关闭管道写端,让子进程知道数据已全部发送。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main() {
    int pipe_to_loop[2];  // Pipe for sending data to loopcmp.c
    int pipe_from_loop[2];  // Pipe for receiving data from loopcmp.c

    // Create the pipes
    if (pipe(pipe_to_loop) == -1 || pipe(pipe_from_loop) == -1) {
        perror("Pipe creation failed");
        return 1;
    }

    // Fork to create a child process for loopcmp.c
    pid_t pid = fork();

    if (pid < 0) {
        perror("Fork failed");
        return 1;
    } else if (pid == 0) {
        // Child process - loopcmp.c
        // Close unused pipe ends
        close(pipe_to_loop[1]);
        close(pipe_from_loop[0]);

        // Duplicate the read end of pipe_to_loop to stdin (file descriptor 0)
        dup2(pipe_to_loop[0], 0);

        // Duplicate the write end of pipe_from_loop to stdout (file descriptor 1)
        dup2(pipe_from_loop[1], 1);

        // Execute loopcmp.c
        execlp("./loopcmp", "./loopcmp", NULL);

        perror("Exec failed");
        return 1;
    } else {
        // Parent process - nicecmp.c
        // Close unused pipe ends
        close(pipe_to_loop[0]);
        close(pipe_from_loop[1]);

        // Data to be sent to loopcmp.c
        const char *str1 = "Hello";
        const char *str2 = "World";
        int number = 42;

        // Send data to loopcmp.c through the pipe
        write(pipe_to_loop[1], str1, strlen(str1) + 1);
        write(pipe_to_loop[1], str2, strlen(str2) + 1);
        write(pipe_to_loop[1], &number, sizeof(int));

        // 关键:关闭写端,告知子进程数据发送完毕
        close(pipe_to_loop[1]);

        // Read data back from loopcmp.c
        int result;
        ssize_t read_bytes = read(pipe_from_loop[0], &result, sizeof(int));
        if (read_bytes != sizeof(int)) {
            perror("Read result failed");
            return 1;
        }

        // Print the result received from loopcmp.c
        printf("Received result from loopcmp.c: %d\n", result);

        // Close remaining pipe end
        close(pipe_from_loop[0]);
    }

    return 0;
}

loopcmp.c(子进程)

核心修改:处理read返回值,按字节读取字符串直到遇到终止符或EOF,避免固定长度读取导致的阻塞。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main() {
    // Data buffers for receiving strings and integer
    char str1[100], str2[100];
    int number;

    // 读取第一个字符串(直到'\0'或EOF)
    ssize_t bytes_read = 0;
    while (bytes_read < sizeof(str1) - 1) {
        ssize_t ret = read(0, str1 + bytes_read, 1);
        if (ret <= 0) break; // 遇到EOF或读取错误
        if (str1[bytes_read] == '\0') break; // 字符串终止符
        bytes_read++;
    }
    str1[sizeof(str1)-1] = '\0'; // 确保字符串安全终止

    // 读取第二个字符串
    bytes_read = 0;
    while (bytes_read < sizeof(str2) - 1) {
        ssize_t ret = read(0, str2 + bytes_read, 1);
        if (ret <= 0) break;
        if (str2[bytes_read] == '\0') break;
        bytes_read++;
    }
    str2[sizeof(str2)-1] = '\0';

    // 读取整数
    ssize_t int_read = read(0, &number, sizeof(int));
    if (int_read != sizeof(int)) {
        fprintf(stderr, "Failed to read integer\n");
        return 1;
    }

    // Print the received data(注:这些输出会写入管道,父进程未读取,若需要父进程接收需额外处理)
    printf("Received strings from nicecmp.c: %s, %s\n", str1, str2);
    printf("Received integer from nicecmp.c: %d\n", number);

    // Send the number 20 back to nicecmp.c through the pipe
    int result = 20;
    write(1, &result, sizeof(int));

    return 0;
}

额外说明

  • 管道是字节流,没有边界,所以不能依赖固定长度读取,必须通过约定的分隔符(如字符串的\0)或先发送数据长度来区分不同数据块。
  • 始终处理read/write的返回值,避免因读取错误或不完整导致的逻辑异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:44:54