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

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

Жанры

Linux программирование в примерах
Шрифт:

POSIX требует, чтобы

O_RDONLY
,
O_RDWR
и
O_WRONLY
были побитово различными, таким образом, гарантируется, что код, подобный только что показанному, будет работать и является простым способом определения того, как был открыт произвольный дескриптор файла.

Используя

F_SETFL
вы можете также изменить эти режимы, хотя по-прежнему применяется проверка прав доступа. Согласно справочной странице GNU/Linux fcnlt(2) флаг
O_APPEND
не может быть сброшен, если он использовался при открытии файла.

9.4.3.4. Неблокирующий ввод/вывод для каналов и FIFO

Ранее для описания

способа работы каналов мы использовали сравнение с двумя людьми, моющими и вытирающими тарелки с использованием сушилки; когда сушилка заполняется, останавливается моющий, а когда она пустеет, останавливается вытирающий. Это блокирующее поведение: производитель или потребитель блокируются в вызове
write
или
read
, ожидая либо освобождения канала, либо появления в нем данных.

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

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

101

Ну, мы игнорируем мысль, что два супруга могли бы хотеть поговорить друг с другом и насладиться компанией — Примеч. автора.

С функцией

open
может использоваться флаг
O_NONBLOCK
для указания неблокирующего ввода/вывода, он может быть установлен и сброшен с помощью
fcntl
. Для
open
и
read
неблокирующий ввод/вывод прост.

Открытие 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 > 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
.

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

Законы Рода. Том 5

Мельник Андрей
5. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 5

Отмороженный 6.0

Гарцевич Евгений Александрович
6. Отмороженный
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Отмороженный 6.0

Двойник Короля 4

Скабер Артемий
4. Двойник Короля
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Двойник Короля 4

Скажи миру – «нет!»

Верещагин Олег Николаевич
1. Путь домой
Фантастика:
фэнтези
героическая фантастика
попаданцы
7.61
рейтинг книги
Скажи миру – «нет!»

Темная сторона. Том 2

Лисина Александра
10. Гибрид
Фантастика:
технофэнтези
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Темная сторона. Том 2

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Я до сих пор не князь. Книга XVI

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

Древесный маг Орловского княжества 4

Павлов Игорь Васильевич
4. Орловское княжество
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества 4

Убивая маску

Метельский Николай Александрович
13. Унесенный ветром
Фантастика:
боевая фантастика
5.75
рейтинг книги
Убивая маску

Афганский рубеж 3

Дорин Михаил
3. Рубеж
Фантастика:
попаданцы
альтернативная история
6.00
рейтинг книги
Афганский рубеж 3

Звездная Кровь. Экзарх I

Рокотов Алексей
1. Экзарх
Фантастика:
боевая фантастика
рпг
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Звездная Кровь. Экзарх I

Кодекс Императора III

Сапфир Олег
3. Кодекс Императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Императора III

Три `Д` для миллиардера. Свадебный салон

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
7.14
рейтинг книги
Три `Д` для миллиардера. Свадебный салон

Барон отрицает правила

Ренгач Евгений
13. Закон сильного
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Барон отрицает правила