Как получить оставшийся размер буфера именованного канала (FIFO) в Linux - PullRequest
0 голосов
/ 07 декабря 2018

В моем приложении я использую именованный канал Linux для потоковой передачи данных.Одно приложение (app1) записывает потоковые данные в этот FIFO, а другое приложение (app2) считывает из него.

Когда размер FIFO заполнен, частичная запись будет записана в FIFO из app1, как Pipe.размер буфера (4096 байт) заполнен.По этой записи сливаются с какой-то другой записью.Так что I want to know what is the remaining size in pipe buffer, прежде чем писать запись.С этим я могу сравнить текущий размер записи с оставшимся размером в буфере канала. Если размер записи больше, то App1 будет ждать и писать полную полную запись всякий раз, когда канал освобождается, так как App2 будет непрерывно читать.Я пытался использовать это, но без использования:

fcntl(fd, F_GETPIPE_SZ );

Также есть ли способ проверить размер буфера этого оставшегося канала с помощью C или C ++?

1 Ответ

0 голосов
/ 07 декабря 2018

Хотя я категорически не одобряю этот подход, существует способ достижения желаемой функциональности, по крайней мере, в некоторых версиях Linux.Для этого нужно использовать ioctl с командой FIONREAD, чтобы получить размер непрочитанных данных внутри канала.Соответствующая команда доступна не во всех 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...