Kniga-Online.club
» » » » Linux программирование в примерах - Роббинс Арнольд

Linux программирование в примерах - Роббинс Арнольд

Читать бесплатно Linux программирование в примерах - Роббинс Арнольд. Жанр: Интернет год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

Открытие FIFO с установленным или сброшенным O_NONBLOCK демонстрирует следующее поведение:

open("/fifо/file", O_RDONLY, mode)

Блокируется до открытия FIFO для записи.

open("/fifo/file", O_RDONLY | O_NONBLOCK, mode)

Открывает файл, возвращаясь немедленно.

open("/fifo/file", O_WRONLY, mode)

Блокирует до открытия FIFO для чтения.

open("/fifo/file", O_WRONLY | O_NONBLOCK, mode)

Если FIFO был открыт для чтения, открывает FIFO и немедленно возвращается. В противном случае возвращает ошибку (возвращаемое значение -1 и errno установлен в ENXIO).

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

read(fd, buf, count) и сброшенный O_NONBLOCK

Функция read() блокируется до тех пор, пока в канал или FIFO не поступят данные.

read(fd, buf, count) и установленный O_NONBLOCK

Функция read() немедленно возвращает -1 с установленным в errno EAGAIN.

В заключение, поведение write() более сложно. Для обсуждения этого нам нужно сначала представить концепцию атомарной записи. Атомарная запись — это такая запись, при которой все данные записываются целиком, не чередуясь с данными от других записей. POSIX определяет в <unistd.h> константу PIPE_BUF. Запись в канал или FIFO данных размером менее или равным PIPE_BUF байтов либо успешно завершается, либо блокируется в соответствии с подробностями, которые мы скоро приведем. Минимальным значением для PIPE_BUF является _POSIX_PIPE_BUF, что равняется 512. Само значение PIPE_BUF может быть больше; современные системы GLIBC определяют ее размер в 4096, но в любом случае следует использовать эту именованную константу и не ожидать, что PIPE_BUF будет иметь то же значение на разных системах.

Во всех случаях для каналов и FIFO write() добавляет данные в конец канала. Это происходит от того факта, что у каналов нет файловых смещений: в них нельзя осуществлять поиск.

Также во всех случаях, как упоминалось, записи размером вплоть до PIPE_BUF являются атомарными: данные не перемежаются с данными от других записей. Данные записи размером более PIPE_BUF байтов могут перемежаться с данными других записей в произвольных границах. Это последнее означает, что вы не можете ожидать, что каждая порция размером PIPE_BUF большого набора данных будет записана атомарно. Установка O_NONBLOCK не влияет на это правило.

Как и в случае с read(), когда O_NONBLOCK не установлен, write() блокируется до тех пор, пока все данные не будут записаны.

Наиболее все усложняется, когда установлен O_NONBLOCK. Канал или FIFO ведут себя следующим образом:

размер ≥ nbytes размер < abytes nbytes ≤ PIPE_BUF write() успешна write() возвращает (-1)/EAGAIN размер > 0 размер = 0 nbytes &gt; PIPE_BUF write() записывает, что может write() возвращает (-1)/EAGAIN

Для файлов, не являющихся каналами и FIFO и к которым может быть применен O_NONBLOCK, поведение следующее:

размер > 0 write() записывает, что может

размер = 0 write() возвращает -1/EAGAIN

Хотя есть ряд сбивающих с толку изменений поведения в зависимости от того, канал это или не канал, установлен O_NONBLOCK или сброшен, есть в канале место для записи или нет, а также в зависимости от размера предполагаемой записи, эти правила предназначены для упрощения программирования:

• Всегда можно отличить конец файла: read() возвращает 0 байтов.

• Если нет доступных для чтения данных, read() либо завершается успешно, либо возвращает указание «нет данных для чтения»: EAGAIN, что означает «попытайтесь снова позже».

• Если для записи нет места, write() либо блокируется до успешного завершения (O_NONBLOCK сброшен), либо завершается неудачей с ошибкой «в данный момент нет места для записи»: EAGAIN.

• Когда место есть, будет записано столько данных, сколько возможно, так что в конечном счете все данные будут переписаны.

Подводя итог, если вы собираетесь использовать неблокирующий ввод/вывод, любой код, который использует write(), должен быть способен обработать укороченную запись, когда успешно записан меньший объем данных, чем было затребовано. Устойчивый код в любом случае должен быть написан таким способом: даже в случае обычного файла диск может оказаться заполненным и write() сможет записать лишь часть данных.

Более того, вы должны быть готовы обработать EAGAIN, понимая, что в этом случае неудача write() не обязательно означает фатальную ошибку. То же верно для кода, использующего для чтения неблокирующий ввод/вывод: признайте, что и здесь EAGAIN не является фатальным. (Однако, может стоит подсчитывать число таких отказов, оставив попытки, когда их слишком много.)

Неблокирующий ввод/вывод действительно усложняет вашу жизнь, в этом нет никакого сомнения. Но для многих приложений он является необходимостью, позволяющей выполнить задание. Снова рассмотрите спулер печати. Демон спулера не может позволить себе находиться в блокирующем read() для файла FIFO, которому представлены входящие задания. Он должен иметь также возможность отслеживать запущенные задания и, возможно, периодически проверять состояние печатающих устройств (например, убедиться, что не заело бумагу).

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

Роббинс Арнольд читать все книги автора по порядку

Роббинс Арнольд - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


Linux программирование в примерах отзывы

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


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

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

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


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