Scroll to navigation

pipe(7) Miscellaneous Information Manual pipe(7)

НАИМЕНОВАНИЕ

pipe - обзор каналов и FIFO

ОПИСАНИЕ

Каналы и FIFO (также называемые именованными каналами) предоставляют двунаправленный канал обмена между процессами. У канала имеется конец для чтения (read end) и конец для записи (write end). Данные, записанные в конец для записи, можно прочитать из конца для чтения.

Канал создаётся с помощью вызова pipe(2), который образует новый канал и возвращает два файловых дескриптора, один указывает на конец для чтения, а другой на конец для записи. Каналы можно использовать для создания канала обмена между процессами; пример смотрите в pipe(2).

У FIFO (сокращение от First In First Out, первым вошёл, первым вышел) имеется имя в файловой системе (создаётся с помощью mkfifo(3)), и такой канал открывается с помощью open(2). Любой процесс может открыть FIFO, если это ему разрешено правами на файл. Конец для чтения открывается при указании флага O_RDONLY; конец для записи открывается при указании флага O_WRONLY. Подробней смотрите fifo(7). Замечание: хотя у FIFO есть путь в файловой системе, при вводе-выводе из FIFO не используются операции с нижележащим устройством (если оно есть).

Ввод-вывод из каналов и FIFO

Каналы и FIFO отличаются только способом создания и открытия. После выполнения этих задач, ввод-вывод из каналов и FIFO имеет одинаковую семантику.

Если процесс пытается выполнить чтение из пустого канала, то read(2) заблокирует выполнение в ожидании данных. Если процесс пытается выполнить запись в заполненный канал (смотрите ниже), то write(2) блокируется до тех пор, пока из канала не будет считано достаточно данных для завершения записи.

Неблокирующий ввод-вывод возможен при использовании операции fcntl(2) F_SETFL для включения флага статуса открытого файла O_NONBLOCK или при открытии fifo(7) с флагом O_NONBLOCK. Если какой-либо процесс открыл канал для записи, операции чтения завершаются с ошибкой EAGAIN; в противном случае—при отсутствии потенциальных отправителей— операции чтения завершаются успешно и возвращают пустой указатель.

Канал обмена, предоставляемый каналом, является потоком байт: какие-либо границы сообщений отсутствуют.

Если все файловые дескрипторы, указывающие на конец канала для записи, были закрыты, то попытка выполнить read(2) из канала возвратит конец файла (read(2) вернёт 0). Если все файловые дескрипторы, указывающие на конец канала для чтения, были закрыты, то write(2) завершится сигналом SIGPIPE, который будет послан вызывающему процессу. Если вызывающий процесс игнорирует этот сигнал, то write(2) завершится ошибкой EPIPE. Приложение, использующее pipe(2) и fork(2), должно использовать правильные вызовы close(2) для закрытия ненужных копий файловых дескрипторов; это обеспечит появления конца файла и доставку SIGPIPE/EPIPE в подходящий момент.

Для канала невозможно вызвать lseek(2).

Ёмкость канала

Канал имеет ограниченную ёмкость. Если канал переполнен, то 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). Начиная с версии Linux 4.5 размер канала по умолчанию составляет менее 16 страниц, если превышен лимит pipe-user-pages-soft.

Следующая операция ioctl(2), которая может быть применена к файловому дескриптору, указывающему на любой конец канала, помещает количество непрочитанных байт канала в буфер int, задаваемый последним аргументом вызова:


ioctl(fd, FIONREAD, &nbytes);

Операция FIONREAD отсутствует в стандартах, но имеется во многих реализациях.

Файлы в /proc

В Linux управление количеством памяти каналов осуществляется через следующие файлы:

/proc/sys/fs/pipe-max-pages (только в Linux 2.6.34)
Верхнее ограничение (в страницах) ёмкости, которое непривилегированный пользователь (без мандата CAP_SYS_RESOURCE) может задать для канала.
Значение по умолчанию этого ограничения равно 16 кратному размеру ёмкости канала по умолчанию (смотрите выше); нижнее ограничение равно 2м страницам.
Данный интерфейс удалён в Linux 2.6.35; его заменяет /proc/sys/fs/pipe-max-size.
/proc/sys/fs/pipe-max-size (начиная с Linux 2.6.35)
Максимальный размер (в байтах) отдельных каналов, который может быть установлен пользователем без мандата CAP_SYS_RESOURCE. Значение, записываемое в этот файл, может округлиться в большую сторону, отражая реальное значение, принятое для удобства реализации. Чтобы определить увеличенное значение, прочитайте содержимое этого файла после записи значения.
Значение по умолчанию равно 1048576 (1 МиБ). Минимальное значение равно размеру системной страницы. При попытке задать меньшее значение вызов write(2) завершится ошибкой EINVAL.
Начиная с Linux 4.9 значение в данном файле также служит верхним пределом ёмкости по умолчанию для новых каналов или открываемых FIFO.
/proc/sys/fs/pipe-user-pages-hard (начиная с Linux 4.5)
Жёсткое ограничение на общий размер (в страницах) всех каналов создаваемых или изменяемых одним непривилегированным пользователем (т. е., без мандата CAP_SYS_RESOURCE или CAP_SYS_ADMIN). Пока общее количество страниц, выделенных под буферы каналов для этого пользователя, равно этому ограничению, попытки создать новые каналы будут отклоняться, также как и попытки увеличить ёмкость канала.
Если значение этого ограничения равно нулю (по умолчанию), то жёсткое ограничение не применяется.
/proc/sys/fs/pipe-user-pages-soft (начиная с Linux 4.5)
"Мягкий" лимит на общий размер (в страницах) всех каналов, созданных или настроенных одним непривилегированным пользователем (то есть пользователем, не имеющим прав CAP_SYS_RESOURCE ни CAP_SYS_ADMIN). Пока общее количество страниц, выделенных для буферов каналов этого пользователя, не превышает установленного лимита, размер отдельных каналов, создаваемых пользователем, будет ограничен двумя страницами (до Linux 5.14 — одной страницей), а попытки увеличить пропускную способность канала будут пресекаться.
Если значение этого ограничения равно нулю, то мягкое ограничение не применяется. По умолчанию значение в этом файле равно 16384, что позволяет создать до 1024 каналов с ёмкостью по умолчанию.

До Linux 4.9 имелись дефекты, влияющие на обработку ограничений pipe-user-pages-soft и pipe-user-pages-hard; смотрите ДЕФЕКТЫ.

PIPE_BUF

Согласно стандарту POSIX.1, запись менее PIPE_BUF байтов должна быть атомарной: выходные данные записываются в канал непрерывной последовательностью. Запись более PIPE_BUF байтов может быть не атомарной: ядро может чередовать данные с данными, записанными другими процессами. Согласно стандарту POSIX.1, значение PIPE_BUF должно быть не менее 512 байт. (В Linux PIPE_BUF равно 4096 байт.) Точная семантика зависит от того, является ли файловый дескриптор неблокирующим (O_NONBLOCK), от того, сколько процессов записывают данные в канал, а также от n, количества записываемых байтов:

Все n байт записываются атомарно; write(2) может заблокироваться, если нет места для немедленной записи n байт
Если есть место для записи n байт в канал, то write(2) немедленно завершается без ошибки, записывая все n байт; в противном случае write(2) завершается с ошибкой, а errno присваивается значение EAGAIN.
Запись не атомарна: данные, переданные во write(2), могут чередоваться с write(2) из других процессов; write(2) блокируется до тех пор, пока не будут записаны n байт.
Если канала переполнен, то write(2) завершается с ошибкой, а errno присваивается значение EAGAIN. В противном случае, может быть записано от 1 до n байт (т. е., может произойти «частичная запись»; вызывающий должен проверить возвращаемое значение write(2), чтобы узнать сколько байт действительно записано), и эти байты могут чередоваться с данными, записанными другими процессами.

Флаги состояния открытого файла

К каналу и FIFO из флагов состояния открытого файла применимы только O_NONBLOCK и O_ASYNC.

Установка флагаO_ASYNC для конца канала, предназначенного для чтения, приводит к тому, что при поступлении новых данных в канал генерируется сигнал (по умолчанию SIGIO). Цель доставки сигналов должна быть установлена с помощью команды fcntl(2) F_SETOWN. В Linux O_ASYNC поддерживается для каналов и FIFO только начиная с версии 2.6.

Замечания о переносимости

В некоторых системах (но не в Linux), каналы являются двунаправленными: данные можно передавать в обоих направлениях между концами канала. Согласно POSIX.1 требуются только однонаправленные каналы. Переносимые приложения не должны зависеть от семантики двунаправленных каналов.

ПРОГРАММНЫЕ ОШИБКИ

До Linux 4.9 имелись дефекты, влияющие на обработку ограничений pipe-user-pages-soft и pipe-user-pages-hard при операции fcntl(2) F_SETPIPE_SZ по изменению ёмкости канала:

(а)
При увеличении ёмкости канала, проверки мягких и жёстких ограничений делались по существующему потреблению и не включали память, требуемую для увеличения ёмкости канала. Новое увеличение ёмкости канала в последствии могло превысить ограничение на общее количество памяти, используемой пользователем для каналов (это могло также вызвать проблему, описанную далее).
Начиная с Linux 4.9 при проверке ограничения добавляется память, требуемая под ёмкость нового канала.
(б)
Проверки ограничения выполнялись даже, когда ёмкость нового канала была меньше чем ёмкость существующего канала. Это могло привести к проблемам, если пользователь устанавливал большую ёмкость канала, а затем ограничения снижались, и в результате этого пользователь больше не мог уменьшить ёмкость канала.
Начиная с Linux 4.9 проверки ограничений выполняются только когда ёмкость канала увеличивается; непривилегированный пользователь всегда может уменьшить ёмкость канала.
(в)
Учёт и проверка ограничений выполнялись следующим образом:
(1)
Выполнялась проверка не превышает ли пользователь ограничение.
(2)
Выделялся буфер под новый канал.
(3)
Учитывалось новое выделение в ограничениях.
Это было рискованно. Несколько процессов могли одновременно пройти этап point (1), а затем выделить буферы канала, которые учитывались только на этапе step (3, в результате чего объем выделенного пользователем буфера канала мог превысить допустимый предел.
Начиная с Linux 4.9, шаг учёта выполняется до выделения и операция завершается с ошибкой, если бы было превышение ограничения.

До выхода Linux 4.9 ошибки, аналогичные пунктам (а) и (в), могли возникать при выделении ядром памяти для нового буфера канала, то есть при вызове pipe(2) и при открытии ранее не открытого FIFO.

СМОТРИТЕ ТАКЖЕ

mkfifo(1), dup(2), fcntl(2), open(2), pipe(2), poll(2), select(2), socketpair(2), splice(2), stat(2), tee(2), vmsplice(2), mkfifo(3), epoll(7), fifo(7)

ПЕРЕВОД

Русский перевод этой страницы руководства разработал(и) Alexey, Azamat Hackimov <azamat.hackimov@gmail.com>, kogamatranslator49 <r.podarov@yandex.ru>, Darima Kogan <silverdk99@gmail.com>, Max Is <ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com> и Aleksandr Felda <afelda@ro.ru>

Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков.

10 июля 2026 г. Linux man-pages 6.20