Чтение онлайн

на главную - закладки

Жанры

Основы программирования в Linux
Шрифт:

На третьем шаге процесс

cat
с самого начала заблокирован в фоновом режиме. Когда
echo
делает доступными некоторые данные, команда
cat
читает их и выводит в стандартный вывод. Обратите внимание на то, что она затем завершается, не дожидаясь дополнительных данных. Программа
cat
не блокируется, т.к. канал уже закрылся, когда завершилась вторая команда, поместившая данные в FIFO, поэтому вызовы
read
в программе
cat
вернут 0 байтов, обозначая этим конец файла.

Теперь, когда

вы посмотрели, как ведут себя каналы FIFO при обращении к ним с помощью программ командной строки, давайте рассмотрим более подробно программный интерфейс, предоставляющий больше возможностей управления операциями чтения и записи при организации доступа к FIFO.

Примечание

В отличие от канала, созданного вызовом

pipe
, FIFO существует как именованный файл, но не как открытый файловый дескриптор, и должен быть открыт перед тем, как можно будет из него читать данные или в него записывать их. Открывается и закрывается канал FIFO с помощью функций
open
и
close
, которые вы ранее применяли к файлам, но с дополнительными функциональными возможностями. Вызову
open
передается полное имя FIFO вместо полного имени обычного файла.

Открытие FIFO с помощью open

Основное ограничение при открытии канала FIFO состоит в том, что программа не может открыть FIFO для чтения и записи с режимом

O_RDWR
. Если программа нарушит это ограничение, результат будет непредсказуемым. Это очень разумное ограничение, т.к., обычно канал FIFO применяется для передачи данных в одном направлении, поэтому нет нужды в режиме
O_RDWR
. Процесс стал бы считывать обратно свой вывод, если бы канал был открыт для чтения/записи.

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

Другое различие между открытием канала FIFO и обычного файла заключается в использовании флага

open_flag
(второй параметр функции
open
) со значением
O_NONBLOCK
. Применение этого режима
open
изменяет способ обработки не только вызова
open
, но и запросов
read
и
write
для возвращаемого файлового дескриптора.

Существует четыре допустимых комбинации значений

O_RDONLY
,
O_WRONLY
и
O_NONBLOCK
флага. Рассмотрим их все по очереди.

open(const char *path, O_RDONLY);

В этом случае вызов

open
блокируется, он не вернет управление программе до тех пор, пока процесс не откроет этот FIFO для записи. Это похоже на первый пример с командой
cat
.

open(const char *path, O_RDONLY | O_NONBLOCK);

Теперь вызов

open
завершится успешно
и вернет управление сразу, даже если канал FIFO не был открыт для записи каким-либо процессом.

open(const char *path, O_WRONLY);

В данном случае вызов

open
будет заблокирован до тех пор, пока процесс не откроет тот же канал FIFO для чтения.

open(const char *path, O_WRONLY | O_NONBLOCK);

Этот вариант вызова всегда будет возвращать управление немедленно, но если ни один процесс не открыл этот канал FIFO для чтения,

open
вернет ошибку, -1, и FIFO не будет открыт. Если есть процесс, открывший FIFO для чтения, возвращенный файловый дескриптор может использоваться для записи в канал FIFO.

Примечание

Обратите внимание на асимметрию в использовании

O_NONBLOCK
с
O_RDONLY
и
O_WRONLY
, заключающуюся в том, что неблокирующий вызов
open
для записи завершается аварийно, если ни один процесс не открыл канал для чтения, а неблокирующий вызов
open
для чтения не возвращает ошибку. На поведение вызова
close
флаг
O_NONBLOCK
влияния не оказывает.

Выполните упражнение 13.11.

Упражнение 13.11. Открытие файлов FIFO

Теперь рассмотрим, как можно использовать поведение вызова

open
с флагом, содержащим
O_NONBLOCK
, для синхронизации двух процессов. Вместо применения нескольких программ-примеров вы напишите одну тестовую программу fifo2.c, которая позволит исследовать поведение каналов FIFO при передаче ей разных параметров.

1. Начните с заголовочных файлов, директивы

#define
и проверки правильности количества предоставленных аргументов командной строки:

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

#define FIFO_NAME "/tmp/my_fifo"

int main(int argc, char *argv[]) {

 int res;

 int open_mode = 0;

 int i;

 if (argc < 2) {

fprintf(stderr, "Usage: %s <some combination of\

O_RDONLY O_WRONLY O_NONBLOCK>\n", *argv);

exit(EXIT_FAILURE);

 }

2. Полагая, что программа передает тестовые данные, вы задаете параметр

open_mode
из следующих аргументов:

 for(i = 1; i <argc; i++) {

if (strncmp(*++argv, "O_RDONLY", 8) == 0) open_mode |= O_RDONLY;

Поделиться:
Популярные книги

Я не князь. Книга XIII

Дрейк Сириус
13. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я не князь. Книга XIII

Последний попаданец 11. Финал. Часть 1

Зубов Константин
11. Последний попаданец
Фантастика:
фэнтези
юмористическое фэнтези
рпг
5.00
рейтинг книги
Последний попаданец 11. Финал. Часть 1

Покоритель Звездных врат

Карелин Сергей Витальевич
1. Повелитель звездных врат
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Покоритель Звездных врат

Совок-8

Агарев Вадим
8. Совок
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Совок-8

Столичный доктор. Том III

Вязовский Алексей
3. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том III

Король Масок. Том 1

Романовский Борис Владимирович
1. Апофеоз Короля
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Король Масок. Том 1

Ищу жену для своего мужа

Кат Зозо
Любовные романы:
любовно-фантастические романы
6.17
рейтинг книги
Ищу жену для своего мужа

Мастер Разума III

Кронос Александр
3. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Мастер Разума III

Темный Охотник 2

Розальев Андрей
2. Темный охотник
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Темный Охотник 2

Идеальный мир для Лекаря 20

Сапфир Олег
20. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 20

Обыкновенные ведьмы средней полосы

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Обыкновенные ведьмы средней полосы

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Адепт. Том 1. Обучение

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
9.27
рейтинг книги
Адепт. Том 1. Обучение

Идущий в тени 4

Амврелий Марк
4. Идущий в тени
Фантастика:
боевая фантастика
6.58
рейтинг книги
Идущий в тени 4