如何在Linux中获取命名管道(FIFO)的剩余缓冲区大小

时间:2018-12-07 19:03:43

标签: c++ linux buffer mkfifo

在我的应用程序中,我使用Linux命名管道进行流数据传输。一个应用程序(app1)将流数据写入此FIFO,其他应用程序(app2)从中读取数据。

当FIFO大小已满时,管道的缓冲区大小(4096字节)将被填充,部分记录将从app1中写入FIFO。这样,记录就与其他记录合并了。因此, I want to know what is the remaining size in pipe buffer ,然后再写记录。这样,我可以将当​​前记录大小与管道缓冲区中的剩余大小进行比较。如果记录大小更大,那么只要管道空闲,App1将等待并写入完整的完整记录,因为App2将连续读取。 我试过使用此方法,但没有用:

fcntl(fd, F_GETPIPE_SZ );

还有没有一种方法可以使用C或C ++检查此剩余管道的缓冲区大小?

1 个答案:

答案 0 :(得分:0)

尽管我强烈反对这种方法,但至少在某些版本的Linux上,有一种方法可以实现所需的功能。为此,需要使用ioctlFIONREAD命令来获取管道内部未读数据的大小。相应的命令并非在所有Linux上都可用,但在我的所有Linux上都可用。

下面的一小段代码显示了如何在实践中应用此技术。请不要考虑太多,它只是用于说明。

#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#include <iostream>

int main() {
    const size_t buf_sz = 4096;
    int fd[2];
    pipe(fd);

    int cap = fcntl(fd[0], F_GETPIPE_SZ);
    std::cout << "Pipe capacity: " << cap << "\n";
    int sz = 0;
    while (((cap - sz) >= buf_sz)) {

        char buf[buf_sz];
        write(fd[1], buf, sizeof(buf));
        ioctl(fd[1], FIONREAD, &sz);
        std::cout << "Avaialble to write: " << cap - sz << "\n";
    }
    std::cout << "No more room in the pipe.\n";
    char buf[buf_sz];
    read(fd[0], buf, buf_sz);
    ioctl(fd[1], FIONREAD, &sz);
    std::cout << "Available now: " << cap - sz << "\n";
}

在我的机器上,它提供以下输出: saristov @ saristovlinux:〜$ g ++ test_pipe.cpp && ./a.out

Pipe capacity: 65536
Avaialble to write: 61440
Avaialble to write: 57344
Avaialble to write: 53248
Avaialble to write: 49152
Avaialble to write: 45056
Avaialble to write: 40960
Avaialble to write: 36864
Avaialble to write: 32768
Avaialble to write: 28672
Avaialble to write: 24576
Avaialble to write: 20480
Avaialble to write: 16384
Avaialble to write: 12288
Avaialble to write: 8192
Avaialble to write: 4096
Avaialble to write: 0

No more room in the pipe.
Available now: 4096