首页 > 解决方案 > 在单个管道中进行多次读取和写入

问题描述

我正在尝试了解 Linux 中的管道。编写了一个基本代码,它将尝试两次写入文件描述符的写入端,然后执行两次读取。在第二次读取时,它被阻塞了。

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

int main()
{
    int filedes[2];
    char buffer1[] = "hello pipe1";
    char buffer2[] = "hello pipe2";
    char readbuffer[30] = {};

    if (pipe(filedes) == 0) {
        printf("Pipe successful\n");
        printf("read from %d, write to %d\n", filedes[0], filedes[1]);
        write(filedes[1], buffer1, sizeof(buffer1));
        perror("write");
        write(filedes[1], buffer2, sizeof(buffer2));
        perror("write");
        read(filedes[0], readbuffer, sizeof(readbuffer));
        printf("read:%s\n", readbuffer);
        read(filedes[0], readbuffer, sizeof(readbuffer));
        printf("read:%s\n", readbuffer);
        close(filedes[1]);
        close(filedes[0]);
    } else {
        perror("pipe failed");
    }
    return 0;
}

我得到输出为“hello pipe1”,然后在第二次读取调用它块第二个缓冲区数据发生了什么。它丢失了吗?

标签: clinuxoperating-systempipeipc

解决方案


您的 readbuffer 是 30 字节,所以这个调用:

read(filedes[0], readbuffer, sizeof(readbuffer));

最多可读取 30 个字节。

您正在编写 24 个字节(每个字符串 11 个字符加上 nul 终止符的 1 个字节)。将read读取所有这些字节。什么都没有丢失。

问题出现在这里:

printf("read:%s\n", readbuffer);

readbuffer 看起来像这样(\0nul 终止符在哪里):

hello pipe1\0hello pipe2\0

当 printf 遇到第一个 nul 时,它会将其视为字符串的结尾,因此只会打印“hello pipe1”。

如果将 readbuffer 大小更改为sizeof(buffer1),这应该可以按预期工作(假设两个输出字符串的大小相同)。


推荐阅读