Scroll to navigation

pipe(2) System Calls Manual pipe(2)

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

pipe, pipe2 - создаёт канал

БИБЛИОТЕКА

Стандартная библиотека языка "Си" (libc, -lc)

СИНОПСИС

#include <unistd.h>
int pipe(int pipefd[2]);
#define _GNU_SOURCE             /* См. feature_test_macros(7) */
#include <fcntl.h>              /* Определение констант O_* */
#include <unistd.h>
int pipe2(int pipefd[2], int flags);
/* На архитектурах Alpha, IA-64, MIPS, SuperH и SPARC/SPARC64 функция pipe() имеет

следующий прототип; смотрите ВЕРСИИ*/
#include <unistd.h>
struct fd_pair {
long fd[2];
};
struct fd_pair pipe(void);

ОПИСАНИЕ

pipe() создает канал — однонаправленный канал передачи данных, который можно использовать для взаимодействия между процессами. Массив pipefd используется для возврата двух файловых дескрипторов, указывающих на концы канала. Дескриптор pipefd[0] указывает на конец канала для чтения. Дескриптор pipefd[1] указывает на конец канала для записи. Данные, записываемые в конец канала для записи, буферизируются ядром до тех пор, пока не будут прочитаны из конца канала для чтения. Подробнее смотрите в pipe(7).

Если flags равно 0, то pipe2() выполняет то же что и pipe(). Следующие значения могут быть побитово сложены в flags для получения различного поведения:

Устанавливает флаг close-on-exec (FD_CLOEXEC) для двух новых открытых файловых дескрипторов. Смотрите описание того же флага в open(2) для того, чтобы узнать как это может пригодиться.
Создаёт канал, в котором ввод-вывод выполняется в «пакетном» режиме. Каждый write(2) в канал рассматривается как отдельный пакет, а read(2) из канала читает один пакет за раз. Заметим следующее:
•
Запись более PIPE_BUF байт (смотрите pipe(7)) будет разделена на несколько пакетов. Константа PIPE_BUF определена в <limits.h>.
•
Если в read(2) указан размер буфера меньше чем следующий пакет, то читается запрашиваемое количество байт, а лишние байты пакета отбрасываются. Указание PIPE_BUF в качестве размера буфера будет достаточно для чтения самых больших пакетов (смотрите предыдущее примечание).
•
Пакеты нулевой длины не поддерживаются (вызов read(2) с нулевым размером буфера ничего не делает и возвращает 0).
Старые ядра, которые не поддерживают этот флаг, возвращают ошибку EINVAL.
Начиная с Linux 4.5, у файлового дескриптора канала возможно менять установку O_DIRECT с помощью fcntl(2).
Устанавливает флаг состояния файла O_NONBLOCK для открытого файлового описания, на которое ссылаются новые файловые дескрипторы. Использование данного флага делает ненужными дополнительные вызовы fcntl(2) для достижения того же результата.
Начиная с версии Linux 5.8, общий механизм уведомлений построен на основе конвейера, в котором ядро объединяет уведомления в конвейеры, открытые в пользовательском пространстве. Владелец конвейера должен указать ядру, за какими источниками событий нужно следить, а также применить фильтры, чтобы выбрать, какие подсобытия отправлять в конвейер.

ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ

В случае успешного выполнения возвращается ноль. В случае ошибки возвращается -1, errno устанавливается для указания на ошибку, а pipefd остается без изменений.

В Linux (и других системах) pipe() не изменяет pipefd при ошибке. Требование стандартизации этого поведения было добавлено в POSIX.1-2008 TC2. Системный вызов Linux pipe2() также не изменяет pipefd при ошибке.

ОШИБКИ

pipefd задан некорректно.
(pipe2()) Некорректное значение flags.
Было достигнуто ограничение по количеству открытых файловых дескрипторов на процесс.
Достигнуто максимальное количество открытых файлов в системе.
Достигнуто жёсткое пользовательское ограничение на выделение памяти для каналов и вызывающий не имеет дополнительных прав; смотрите pipe(7).
(pipe2()) O_NOTIFICATION_PIPE был передан в flags, а поддержка уведомлений (CONFIG_WATCH_QUEUE) не скомпилирована в ядро.

ВЕРСИИ

System V ABI на некоторых архитектурах позволяет использовать более одного регистра для возврата нескольких значений; в нескольких архитектурах (Alpha, IA-64, MIPS, SuperH и SPARC/SPARC64) использована эта возможность для реализации системного вызова pipe() подобно функциям: вызов не использует параметры и при успешном выполнении возвращает пару файловых дескрипторов как результат. Обёрточная функция glibc pipe() учитывает это. Описание регистров хранения второго файлового дескриптора смотрите в syscall(2).

СТАНДАРТЫ

POSIX.1-2024.

ИСТОРИЯ

POSIX.1-2001.
POSIX.1-2024. Linux 2.6.27, glibc 2.9.

ПРИМЕРЫ

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

Исходный код программы

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{

int pipefd[2];
char buf;
pid_t cpid;
if (argc != 2) {
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1)
err(EXIT_FAILURE, "pipe");
cpid = fork();
if (cpid == -1)
err(EXIT_FAILURE, "fork");
if (cpid == 0) { /* Child reads from pipe */
if (close(pipefd[1]) == -1) /* Close unused write end */
err(EXIT_FAILURE, "close");
while (read(pipefd[0], &buf, 1) > 0) {
if (write(STDOUT_FILENO, &buf, 1) != 1)
err(EXIT_FAILURE, "write");
}
if (write(STDOUT_FILENO, "\n", 1) != 1)
err(EXIT_FAILURE, "write");
if (close(pipefd[0]) == -1)
err(EXIT_FAILURE, "close");
_exit(EXIT_SUCCESS);
} else { /* Parent writes argv[1] to pipe */
if (close(pipefd[0]) == -1) /* Close unused read end */
err(EXIT_FAILURE, "close");
if (write(pipefd[1], argv[1], strlen(argv[1])) != strlen(argv[1]))
err(EXIT_FAILURE, "write");
if (close(pipefd[1]) == -1) /* Reader will see EOF */
err(EXIT_FAILURE, "close");
if (wait(NULL) == -1) /* Wait for child */
err(EXIT_FAILURE, "wait");
exit(EXIT_SUCCESS);
} }

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

fork(2), read(2), socketpair(2), splice(2), tee(2), vmsplice(2), write(2), popen(3), pipe(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 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

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

08.02.2026 Linux man-pages 6.20