Читаем Linux API. Исчерпывающее руководство полностью

fatal("Can't read response from server");

printf("%d\n", resp.seqNum);

exit(EXIT_SUCCESS);

}

pipes/fifo_seqnum_client.c

44.9. Неблокирующий ввод/вывод

Как отмечалось ранее, при открытии очереди FIFO процесс блокируется, если другой ее конец еще не был открыт. Иногда такая блокировка является нежелательной, и для этих случаев при вызове open() можно указать флаг O_NONBLOCK:

fd = open("fifopath", O_RDONLY | O_NONBLOCK);

if (fd == -1)

errExit("open");

Если другой конец очереди уже открыт, то флаг O_NONBLOCK никак не влияет на вызов open() — очередь сразу же успешно открывается, как обычно. Действие этого флага проявляется только в случае, если другой конец очереди FIFO еще не открыт, и зависит оно от того, какой именно конец открывается — считывающий или записывающий:

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

• если очередь FIFO открывается для записи и ни один процесс не подключен к ее считывающему концу, то вызов open() завершается ошибкой ENXIO.

Асимметричность флага O_NONBLOCK, зависящая от того, какой конец очереди FIFO открывается, можно объяснить следующим образом. При открытии очереди для чтения отсутствие записывающего процесса не является проблемой, поскольку любая попытка чтения из очереди просто не возвращает никаких данных. Но если попытаться записать в очередь, к которой не подключен считывающий процесс, то вызов write() приведет к получению сигнала SIGPIPE и ошибки EPIPE.

В табл. 44.1 описывается семантика открытия очереди FIFO, в том числе и с учетом флага O_NONBLOCK, описанного выше.

Таблица 44.1. Семантика вызова open() для очереди FIFO

Тип open()

Результат вызова open()

Открытие для

Дополнительные флаги

Другой конец FIFO открыт

Другой конец FIFO закрыт

Чтение

Нет (блокировка)

Сразу же успешно завершается

Блокируется

O_NONBLOCK

Сразу же успешно завершается

Сразу же успешно завершается

Запись

Нет (блокировка)

Сразу же успешно завершается

Блокируется

O_NONBLOCK

Сразу же успешно завершается

Выдается ошибка (ENXIO)

Использование флага O_NONBLOCK при открытии очередей FIFO служит двум основным целям:

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

• предотвращает взаимную блокировку процессов, которые открывают две очереди FIFO.

Взаимная блокировка — ситуация, при которой два или более процесса блокируются, потому что каждый из них ждет, когда другой завершит выполнение каких-то действий. Два процесса, изображенные на рис. 44.8, блокируют друг друга. Каждый из них ждет возможности открыть очередь FIFO для чтения. Такого положения можно было бы избежать, если бы каждый из процессов мог выполнить свой следующий шаг (открытие очереди для записи). Эту конкретную проблему можно было бы решить, изменив порядок выполнения шагов 1 и 2 в процессе Y, не трогая процесс X (или наоборот). Однако в некоторых приложениях достичь такого порядка выполнения может быть непросто. Вместо этого при открытии очереди FIFO для чтения один из процессов (или оба) может указать флаг O_NONBLOCK.

Рис. 44.8.Взаимная блокировка процессов, открывающих две очереди FIFO

Неблокирующие чтение и запись

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

Но иногда нужно изменить состояние флага O_NONBLOCK для очереди FIFO (или файла другого типа). Такая необходимость может возникнуть в следующих случаях.

• Очередь FIFO открыта с флагом O_NONBLOCK, но мы хотим, чтобы последующие вызовы read() и write() выполнялись в блокирующем режиме.

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

• Логика нашего приложения может потребовать установки и сброса флага O_NONBLOCK для какого-нибудь файлового дескриптора.

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

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных