e-knigi.com

Основы программирования в Linux - Мэтью Нейл

На этом ресурсе Вы можете бесплатно читать книгу онлайн Основы программирования в Linux - Мэтью Нейл. Жанр: Программирование . На сайте e-Knigi.com Вы можете онлайн читать полную версию книги без регистрации и sms. Так же Вы можете ознакомится с содержанием, описанием, предисловием о произведении
Перейти на страницу:
Упражнение 13.10. Организации доступа к файлу FIFO

1. Сначала попробуйте прочесть (пустой) файл FIFO:

$ <b>cat &lt; /tmp/my_fifo</b>

2. Теперь попытайтесь записать в FIFO. Вам придется использовать другой терминал, поскольку первая команда в данный момент "зависла" в ожидании появления каких-нибудь данных в FIFO:

$ <b>echo &quot;Hello World&quot; &gt; /tmp/my_fifo</b>

Вы увидите вывод команды

cat
. Если не посылать никаких данных в канал FIFO, команда
cat
будет ждать до тех пор, пока вы не прервете ее выполнение, традиционно комбинацией клавиш <Ctrl>+<C>.

3. Можно выполнить обе команды одновременно, переведя первую в фоновый режим:

$ <b>cat &lt; /tmp/my_fifo &amp;</b>

[1] 1316

$ <b>echo &quot;Hello World&quot; &gt; /tmp/my_fifo</b>

Hello World

[1]+ Done   cat &lt;/tmp/my_fifo

$

Как это работает

Поскольку в канале FIFO не было данных, обе команды,

cat
и
echo
, приостанавливают выполнение, ожидая, соответственно, поступления каких-нибудь данных и какого-либо процесса для их чтения.

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

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 &lt;unistd.h&gt;

Перейти на страницу:

Мэтью Нейл читать все книги автора по порядку

Мэтью Нейл - на сайте онлайн книг e-Knigi.com Вы можете читать полные версии книг автора в одном месте.


Основы программирования в Linux отзывы

Отзывы читателей о книге Основы программирования в Linux, автор: Мэтью Нейл. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администрация сайта e-Knigi.com


Прокомментировать
Подтвердите что вы не робот:*