Где ядро ​​Linux хранит данные, записанные в канал

Предположим следующий простой код:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

main()
{
    int fd[2];                
    pipe(fd);
 // ...               
    write(fd, buf, VERY_BIG_NUMBER);
 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
}

Теперь мои вопросы:

  1. Может кто-нибудь объяснить, где запись будет помещать данные?
  2. Это записано в некоторый буфер, расположенный в пользовательском пространстве или пространстве ядра?
  3. Какова максимальная длина, которую можно записать в трубу?
  4. Поскольку конвейерная запись является блокирующей операцией, разве ядро ​​для эффективности просто ничего не делает и ждет, пока читатель передаст данные непосредственно ему?

1 ответ

Решение

В Linux есть конвейерный буфер, обычно 64 КБ. Записывает в буфер трубы. Как только он заполнится write() syscall блокируется, пока другой конец трубы не опустошит буфер.

Выдержка из справочной страницы по трубе (7):

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

В версиях Linux до 2.6.11 емкость канала была такой же, как размер системной страницы (например, 4096 байт на i386). Начиная с Linux 2.6.11 емкость канала составляет 65536 байт.

Буфер находится в пространстве ядра. Трубы реализуются через виртуальную файловую систему pipefs. Код ядра для этой файловой системы выделяет 16 страниц по 4 КБ для каждого pipe2() системный вызов, и это буферное пространство связано с индексом, созданным для канала. read() а также write() Системные вызовы копируют данные в пользовательское пространство и из него. ( Источник)

Записи в канал являются атомарными, если они меньше 4 КБ. Запись более 4 КБ может привести к ошибкам страницы и, следовательно, больше не является атомарной. Это означает, что множественные записи из отдельных процессов могут чередоваться, если записи превышают 4 КБ.

Смотрите также: Насколько велика труба буфера?

Другие вопросы по тегам