Где ядро Linux хранит данные, записанные в канал
Предположим следующий простой код:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
main()
{
int fd[2];
pipe(fd);
// ...
write(fd, buf, VERY_BIG_NUMBER);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
Теперь мои вопросы:
- Может кто-нибудь объяснить, где запись будет помещать данные?
- Это записано в некоторый буфер, расположенный в пользовательском пространстве или пространстве ядра?
- Какова максимальная длина, которую можно записать в трубу?
- Поскольку конвейерная запись является блокирующей операцией, разве ядро для эффективности просто ничего не делает и ждет, пока читатель передаст данные непосредственно ему?
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 КБ.
Смотрите также: Насколько велика труба буфера?