Иногда программистам нужно, чтобы вызов readO в случае, когда данные
недоступны, не блокировался. Они предпочитают, чтобы вызов сразу же возвращал
какое-то значение, указывая, что данных для считывания нет. Это называется
вводом-выводом без блокировки (nonblocking I/O ) и позволяет приложениям
выполнять ввод-вывод, возможно, даже на нескольких файлах, вообще
не блокируясь и, следовательно, не упуская доступные данные в других
файлах.
Следовательно, стоит проверять еще одно значение переменной error: EAGAIN.
Как говорилось ранее, если определенный дескриптор файла открывается в режиме
без блокирования (вызову openО передан флаг 0_N0NBL0CK; см. раздел
«Флаги для системного вызова ореп()»), но данных для считывания нет, то вызов
read() возвращает значение -1 и устанавливает для переменной error значение
EAGAIN, а не блокируется. При выполнении считывания без блокировки необходимо
всегда проверять error на значение EAGAIN, чтобы не спутать
серьезную ошибку с простым отсутствием данных. Например, можно использовать
такой код:
char buf[BUFSIZ].
ssize_t nr.
start
nr = read (fd. buf. BUFSIZ).
if (nr - 1) {
if (errno == EINTR)
goto start: /* о. тише! */
if (errno == EAGAIN)
/* повторить позже */
else
/* ошибка */
}
ПРИМЕЧАНИЕ
Обработка значения ошибки EAGAIN в этом примере с использованием инструкции goto start
в действительности несет мало смысла - можно с таким же успехом вообще не использовать
ввод-вывод без блокировки. Использование режима без блокировки экономит время, но приводит
к увеличению нагрузки из-за повторяющихся циклов.