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

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

int flags;

flags = fcntl(fd, F_GETFL); /* Получаем флаги состояния открытых файлов */

flags |= O_NONBLOCK; /* Включаем бит O_NONBLOCK */

fcntl(fd, F_SETFL, flags); /* Обновляем флаги состояния открытых файлов */

А для его выключения достаточно следующих строк:

flags = fcntl(fd, F_GETFL);

flags &= ~O_NONBLOCK; /* Выключаем бит O_NONBLOCK */

fcntl(fd, F_SETFL, flags);

44.10. Семантика вызовов read() и write() в контексте каналов и очередей FIFO

В табл. 44.2 описана семантика операции read() для каналов и очередей FIFO, в том числе и с учетом действия флага O_NONBLOCK.

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

Таблица 44.2. Семантика чтения n байт из канала или очереди FIFO, содержащих p байт

O_NONBLOCK включен?

Данные, доступные в канале или очереди FIFO (p)

p = 0, записывающий конец открыт

p = 0, записывающий конец закрыт

p < n

p >= n

Нет

Блокируется

Возвращает 0 (EOF)

Считывает p байт

Считывает n байт

Да

Возникает ошибка (EAGAIN)

Возвращает 0 (EOF)

Считывает p байт

Считывает n байт

Влияние флага O_NONBLOCK на запись в канал или очередь FIFO оказывается более сложным из-за наличия ограничения PIPE_BUF. Поведение операции write() описано в табл. 44.3.

Таблица 44.3. Семантика записи n байт в канал или очередь FIFO

O_NONBLOCK включен?

Считывающий конец открыт

Считывающий конец закрыт

n <= PIPE_BUF

n > PIPE_BUF

Нет

Автоматически записывает n байт; может блокироваться, пока не будет прочитано достаточно данных, чтобы можно было выполнить write()

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

SIGPIPE + EPIPE

Да

Если для немедленной записи n байт достаточно места, write() завершается успешно автоматически; в противном случае возвращается ошибка EAGAIN

Если у нас хватает места для немедленной записи некоего количества данных, записывается от 1 до n байт (которые могут перемешаться с данными, записываемыми другими процессами); в противном случае write() завершается ошибкой EAGAIN

Флаг O_NONBLOCK приводит к сбою записи в канал или очередь FIFO (с ошибкой EAGAIN) в любой ситуации, в которой немедленная передача данных невозможна. Это значит следующее: при записи PIPE_BUF байт вызов write() завершится неудачей, если в канале или очереди FIFO окажется недостаточно места; такая ситуация связана с тем, что ядро не может немедленно завершить операцию и в то же время не может выполнить частичную запись, поскольку это бы нарушило требование к атомарности записи сообщений, не превышающих PIPE_BUF байт.

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

44.11. Резюме

Каналы стали первым средством межпроцессного взаимодействия в UNIX-системах. Они часто используются в командной оболочке и других приложениях. Канал является однонаправленным потоком байтов с ограниченной пропускной способностью, который можно применять для организации взаимодействия родственных процессов. В него можно записать блок данных любого размера, но только блоки, не превышающие PIPE_BUF байт, являются гарантировано атомарными. Каналы применяются не только для IPC, но и как метод синхронизации процессов.

Задействуя каналы, следует проявлять осмотрительность при закрытии неиспользуемых дескрипторов, чтобы считывающий процесс смог обнаружить символ конца файла, а записывающий процесс — получить сигнал SIGPIPE или ошибку EPIPE (обычно проще всего сделать так, чтобы записывающий процесс игнорировал сигнал SIGPIPE и обнаруживал «сбой» канала с помощью ошибки EPIPE).

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

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

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

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

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

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

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

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

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