Установить размер буфера трубы - PullRequest
13 голосов
/ 07 марта 2011

У меня есть многопоточное приложение C ++, которое использует конвейеры posix для эффективного выполнения межпотокового взаимодействия (поэтому мне не нужно сходить с ума из-за тупиков).

Я установил операцию записи безблокировка, поэтому писатель получит сообщение об ошибке, если в буфере недостаточно места для записи.

if((pipe(pipe_des)) == -1)
    throw PipeException();

int flags = fcntl(pipe_des[1], F_GETFL, 0); // set write operation non-blocking
assert(flags != -1);
fcntl(pipe_des[1], F_SETFL, flags | O_NONBLOCK);

Теперь я хотел бы установить размер буфера канала в пользовательское значение (одно слово вконкретный случай).

Я гуглил, но не смог найти ничего полезного.Есть ли способ (возможно, posix-совместимый) сделать это?

Спасибо

Лоренцо

PS: я нахожусь под Linux (если это может быть полезно)

Ответы [ 3 ]

14 голосов
/ 17 января 2013

Поскольку вы упомянули, что вы работаете в Linux и, возможно, не против переносимости, вас может заинтересовать манипулятор дескриптора файла F_SETPIPE_SZ, доступный с Linux 2.6.35.

int pipe_sz = fcntl(pipe_des[1], F_SETPIPE_SZ, sizeof(size_t));

Вы обнаружите, что pipe_sz == getpagesize() после этого вызова, так как буфер не может быть меньше размера системной страницы. См. fcntl(2).

3 голосов
/ 07 марта 2011

Я гуглил "размер буфера Linux-канала" и получил это как верхняя ссылка .Как правило, ограничение составляет 64 КБ, и оно жестко запрограммировано.

Редактировать Ссылка не работает, и в любом случае она, вероятно, была неправильной.Справочная страница Linux pipe (7) гласит:

Канал имеет ограниченную емкость.Если канал заполнен, то write (2) заблокируется или завершится с ошибкой, в зависимости от того, установлен ли флаг O_NONBLOCK (см. Ниже).Разные реализации имеют разные пределы для пропускной способности трубы.Приложения не должны полагаться на определенную емкость: приложение должно быть спроектировано так, чтобы процесс чтения потреблял данные, как только он стал доступен, чтобы процесс записи не оставался заблокированным.

В версиях Linux до 2.6.11, емкость канала была такой же, как размер системной страницы (например, 4096 байт на i386).Начиная с Linux 2.6.11, объем канала составляет 16 страниц (т. Е. 65 536 байт в системе с размером страницы 4096 байт).Начиная с Linux 2.6.35, объем канала по умолчанию составляет 16 страниц, но его можно запросить и установить с помощью операций fcntl (2) F_GETPIPE_SZ и F_SETPIPE_SZ.См. Fcntl (2) для получения дополнительной информации.

В любом случае, IMO по-прежнему действует следующее:

Я не уверен, почему вы пытаетесь установить ограничение ниже, похоже,странная идея для меня.Если вы хотите, чтобы писатель подождал, пока читатель обработает написанное, вы должны использовать канал в другом направлении, чтобы читатель отправил обратно подтверждение.

2 голосов
/ 07 марта 2011

Вы можете использовать область общей памяти (как в System V) из двух слов: одно для отправки данных, а другое для получения данных, и реализовывать свои каналы с ними. другие решения, как вы могли найти ранее, касаются перекомпиляции ядра так, как вы хотели бы, чтобы оно было, но я полагаю, что это не так.

Ciao!

...