fifo - спецфайл, организующий очередь (first-in first-out) и называемый каналом
ОПИСАНИЕ
Спецфайл FIFO (называемый каналом) похож на канал, кроме того, что к нему можно осуществить доступ, как к части файловой системы. Он может быть открыт многими процессами для записи и чтения. Когда процессы обмениваются данными через FIFO, ядро передает их без записи в файловую систему. Поэтому спецфайл FIFO ничего не содержит в файловой системе. Запись в файловой системе служит процессу при организации доступа к каналу через файловую систему ссылкой.
Ядро поддерживает один канал для каждого спецфайла FIFO, который открыт хотя бы одним процессом. Для того, чтобы пропускать данные FIFO должен быть открыт как для чтения, так и для записи. Обычно при открытии FIFO он блокируется до тех пор, пока вышеописанные условия не будут выполнены.
Процесс может открыть FIFO в неблокирующе режиме. В этом случае спецфайл открывается только для чтения, даже если никто не открывал его для записи; если это произойдет, то вернется сообщение об ошибке ENXIO (такого устройства или адреса не существует), хотя файл открыт для чтения.
В Linux открытие FIFO для чтения и записи может быть осуществлено в блокирующем и неблокирующем режимах. Так как POSIX не описывает эти положения, это может быть использовано для открытия FIFO для чтения в отсутствие считывающих процессов. Процесс, использующий этот файл для чтения и записи (для связи с самим собой), не должен допустить возникновения безвыходных ситуаций.
MKFIFO
mkfifo - создает особый FIFO-файл (именованный канал)
СИНТАКСИС
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
ОПИСАНИЕ
Функция mkfifo создает особый FIFO-файл с названием pathname. mode определяет уровни доступа для FIFO. Они меняются с помощью процесса umask обычным путем: уровни доступа для созданного файла есть (mode & ~umask).
Особый FIFO-файл похож на обычный канал, только он создается другим путем. Вместо того, чтобы быть анонимным каналом связи, особый FIFO-файл подключается к системе с помощью вызова mkfifo.
Как только таким образом создан особый FIFO-файл, любой процесс может открыть его для чтения или записи так же, как и любой обычный файл. Тем не менее, он должен быть открытым в обоих состояниях одновременно, прежде чем Вы захотите провести в нем операции ввода или вывода. Однако, открытие FIFO для чтения обычно блокирует его до тех пор, пока другой процесс не откроет этот же FIFO для записи, и наоборот.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Обычно возвращаемое значение при успешном завершении работы mkfifo равно 0. В случае ошибки возвращается -1, при этом значение переменной errno изменяется соответственно ошибке.
Пример программы
Программа server читает символы из файла и передаёт их через именованный канал программе client, которая вычисляет общее количество переданных символов.
Текст программы
Файл server.c
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#define PERM 0666 //права доступа к именованному каналу
int fd; //дескриптор файла с данными
int fdw; //дескриптор канала для записи
char buff[1]; //буфер для данных
int main(void)
{
printf("\n\t.:SERVER:.\n\n");
if((mkfifo("fifo",PERM,0))<0) //создаём именованный канал с именем fifo
{perror("\n\tError (server - mkfifo)");return 0;}
if((fdw=open("fifo",O_WRONLY))<0) //открываем его для записи
{perror("\n\tError (server - open fifo)");return 0;}
if((fd=open("data.txt",O_RDONLY))<0)//открываем файл с данными для чтения
{perror("\n\tError (server - open file)");return 0;}
while(read(fd,buff,1)&&(buff[0]!=EOF))//читаем из файла символы до конца
{ //файла
printf("buff=%c\n",buff[0]); //выводим прочитанный символ на экран
write(fdw,buff,1); //и записываем его в канал
}
close(fdw); //закрываем дескриптор канала для записи
return 0;
}
Файл client.c
#include <stdio.h>
#include <fcntl.h>
char buff[1]; //буфер для данных
int n; //количество прочитанных символов
int fdr; //дескриптор канала для чтения
int count=0; //общее количество символов
int main(void)
{
printf("\n\t.:CLIENT:.\n\n");
if((fdr=open("fifo",O_RDONLY))<0) //открываем канал для чтения
{perror("\n\tError (client - open fifo)");return 0;}
while(n=read(fdr,buff,1)>0) //читаем из канала символы
{
printf("buff=%c\n",buff[0]); //выводим прочитанный символ на экран
count++; //увеличиваем счётчик
}
printf("\n\tTotal amount of symbols: %d\n",count);//общее кол-во символов
close(fdr); //закрываем дескриптор канала для чтения
return 0;
}
IPC
ipc - межпроцессные коммуникационные механизмы System V