Scroll to navigation

PIPE(2) Руководство программиста Linux PIPE(2)

ИМЯ

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

ОБЗОР

#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);

ОПИСАНИЕ

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

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

Устанавливает флаг состояния файла O_NONBLOCK для двух новых открытых файловых дескрипторов. Использование данного флага заменяет дополнительные вызовы fcntl(2) для достижения того же результата.
Устанавливает флаг close-on-exec (FD_CLOEXEC) для двух новых открытых файловых дескрипторов. Смотрите описание того же флага в open(2) для того, чтобы узнать как это может пригодиться.

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

При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

ОШИБКИ

pipefd задан некорректно.
(pipe2()) Некорректное значение flags.
Процесс открыл слишком много файловых дескрипторов.
Достигнуто максимальное количество открытых файлов в системе.

ВЕРСИИ

Вызов pipe2() был добавлен в Linux начиная с версии 2.6.27; поддержка в glibc появилась начиная с версии 2.9.

СООТВЕТСТВИЕ СТАНДАРТАМ

pipe(): POSIX.1-2001.

Вызов pipe2() есть только в Linux.

ПРИМЕР

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

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

int pipefd[2];
pid_t cpid;
char buf;
if (argc != 2) { fprintf(stderr, "Использование: %s <строка>\n", argv[0]); exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Потомок читает из канала */
close(pipefd[1]); /* Закрывает неиспользуемый конец для записи */
while (read(pipefd[0], &buf, 1) > 0)
write(STDOUT_FILENO, &buf, 1);
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);
} else { /* Родитель пишет значение argv[1] в канал */
close(pipefd[0]); /* Закрывает неиспользуемый конец для чтения */
write(pipefd[1], argv[1], strlen(argv[1]));
close(pipefd[1]); /* Читатель видит EOF */
wait(NULL); /* Ожидание потомка */
exit(EXIT_SUCCESS);
} }

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

fork(2), read(2), socketpair(2), write(2), popen(3), pipe(7)

2012-02-14 Linux