Главная » 2017 » Ноябрь » 21 » man 2 pipe
01:16
man 2 pipe

SEO sprint - Всё для максимальной раскрутки!





ИМЯ


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_CLOEXEC
Устанавливает флаг close-on-exec (FD_CLOEXEC) для двух новых открытых
файловых дескрипторов. Смотрите описание того же флага в open(2) для того,
чтобы узнать как это может пригодиться.

O_DIRECT (начиная с Linux 3.4)
Создаёт канал, в котором ввод-вывод выполняется в «пакетном» режиме. Каждый
write(2) в канал рассматривается как отдельный пакет, а read(2) из канала
читает один пакет за раз. Заметим следующее:

* Запись более PIPE_BUF байт (смотрите pipe(7)) будет разделена на
несколько пакетов. Константа PIPE_BUF определена в <limits.h>.

* Если в read(2) указан размер буфера меньше чем следующий пакет, то
читается запрашиваемое количество байт, а лишние байты пакета
отбрасываются. Указание PIPE_BUF в качестве размера буфера будет
достаточно для чтения самых больших пакетов (смотрите предыдущее
примечание).

* Пакеты нулевой длины не поддерживаются (вызов read(2) с нулевым размером
буфера ничего не делает и возвращает 0).

Старые ядра, которые не поддерживают этот флаг, возвращают ошибку EINVAL.

O_NONBLOCK
Устанавливает флаг состояния файла O_NONBLOCK для двух новых открытых
файловых дескрипторов. Использование данного флага заменяет дополнительные
вызовы fcntl(2) для достижения того же результата.



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


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

EMFILE Было достигнуто ограничение по количеству открытых файловых дескрипторов на
процесс.

ENFILE Достигнуто максимальное количество открытых файлов в системе.

ENFILE Достигнуто жёсткое пользовательское ограничение на выделение памяти для
каналов и вызывающий не имеет дополнительных прав; смотрите pipe(7).



ВЕРСИИ


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



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


pipe(): POSIX.1-2001, POSIX.1-2008.

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



ПРИМЕР


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

Исходный код программы
#include <sys/types.h>
#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 <string>\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);
}


} 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), splice(2), tee(2), vmsplice(2), write(2),
popen(3), pipe(7)



Категория: (2) Системные вызовы ядра (функции языка Си) | Просмотров: 757 | Добавил: Администратор | Рейтинг: 0.0/0
Всего комментариев: 0
avatar