4. Запись числа байтов, меньшего емкости канала или FIFO, гарантированно атомарно. Это означает, что в случае, когда несколько процессов одновременно записывают в канал, порции данных от этих процессов не перемешиваются.
5. При записи большего числа байтов, чем это позволяет канал или FIFO, вызов SIGPIPE
, а вызов errno=ERRPIPE
) (если процесс не установил обработки сигнала SIGPIPE
, производится обработка по умолчанию — процесс завершается).
В качестве примера приведем простейший пример приложения клиент- сервер, использующего FIFO для обмена данными. Следуя традиции, клиент посылает серверу сообщение "Здравствуй, Мир!", а сервер выводит это сообщение на терминал.
#include
#include
#define FIFO "fifo.1"
#define MAXBUFF 80
main {
int readfd, n;
char buff[MAXBUFF]; /* буфер для чтения данных из FIFO */
/* Создадим специальный файл FIFO с открытыми для всех
правами доступа на чтение и запись */
if (mknod(FIFO, S_IFIFO | 0666, 0) < 0) {
printf("Невозможно создать FIFO\n");
exit(1);
}
/* Получим доступ к FIFO */
if ((readfd = open(FIFO, O_RDONLY)) < 0) {
printf("Невозможно открыть FIFO\n");
exit(1);
}
/* Прочитаем сообщение ("Здравствуй, Мир!") и выведем его
на экран */
while ((n = read(readfd, buff, MAXBUFF)) > 0)
if {write(1, buff, n) != n) {
printf("Ошибка вывода\n");
exit(1);
}
/* Закроем FIFO, удаление FIFO - дело клиента */
close(readfd);
exit(0);
}
#include
#include
/* Соглашение об имени FIFO */
#define FIFO "fifo.1"
main {
int writefd, n;
/* Получим доступ к FIFO */
if ((writefd = open(FIFO, O_WRONLY)) < 0) {
printf("Невозможно открыть FIFO\n");
exit(1);
}
/* Передадим сообщение серверу FIFO */
if (write(writefd, "Здравствуй, Мир!\n", 18) != 18) {
printf("Ошибка записи\n");
exit(1);
}
/* Закроем FIFO */
close(writefd);
/* Удалим FIFO */
if (unlink(FIFO) < 0) {
printf("Невозможно удалить FIFO\n");
exit(1);
}
exit(0);
}
Идентификаторы и имена в IPC
Как было показано, отсутствие имен у каналов делает их недоступными для независимых процессов. Этот недостаток устранен у FIFO, которые имеют имена. Другие средства межпроцессного взаимодействия, являющиеся более сложными, требуют дополнительных соглашений по именам и идентификаторам. Множество возможных имен объектов конкретного типа межпроцессного взаимодействия называется
Для таких объектов IPC, как очереди сообщений, семафоры и разделяемая память, процесс назначения имени является более сложным, чем просто указание имени файла. Имя для этих объектов называется ключом (key) и генерируется функцией
#include
#include
key_t ftok(char* filename, char proj);
В качестве filename
можно использовать имя некоторого файла, известное взаимодействующим процессам. Например, это может быть имя программы-сервера. Важно, чтобы этот файл существовал на момент создания ключа. Также нежелательно использовать имя файла, который создается и удаляется в процессе работы распределенного приложения, поскольку при генерации ключа используется номер inode файла. Вновь созданный файл может иметь другой inode и впоследствии процесс, желающий иметь доступ к объекту, получит неверный ключ.