Глава 16 Неблокируемый ввод-вывод

Глава 16

Неблокируемый ввод-вывод

16.1. Введение

По умолчанию сокеты блокируют выполнение процесса. Это означает, что, когда мы вызываем на сокете функцию, которая не может выполниться немедленно, наш процесс переходит в «спящее» состояние и ждет, когда будет выполнено определенное условие. Мы можем разделить функции сокетов, способные вызвать блокирование, на четыре категории.

1. Операции ввода: функции read, readv, recv, recvfrom и recvmsg. Если мы вызываем одну из этих функций ввода для блокируемого сокета TCP (а по умолчанию такой сокет является блокируемым) и в приемном буфере сокета отсутствуют данные, то сокет вызывает переход в спящее состояние на то время, пока не придут какие-нибудь данные. Поскольку TCP является протоколом байтового потока, из этого состояния мы выйдем, когда придет «хоть сколько- нибудь» данных: это может быть одиночный байт, а может быть и целый сегмент данных TCP. Если мы хотим ждать до тех пор, пока не будет доступно определенное фиксированное количество данных, мы вызываем нашу функцию readn (см. листинг 3.9) или задаем флаг MSG_WAITALL (см. табл. 14.1). Поскольку UDP является протоколом дейтаграмм, то если приемный буфер блокируемого сокета UDP пуст, мы переходим в состояние ожидания и находимся в нем до тех пор, пока не придет дейтаграмма UDP.

В случае неблокируемого сокета при невозможности удовлетворить условию операции ввода (как минимум 1 байт данных для сокета TCP или целая дейтаграмма для сокета UDP) возврат происходит немедленно с ошибкой EWOULDBLOCK.

2. Операции вывода: функции write, writev, send, sendto, и sendmsg. В отношении сокета TCP в разделе 2.9 мы сказали, что ядро копирует данные из буфера приложения в буфер отправки сокета. Если для блокируемого сокета недостаточно места в буфере отправки, процесс переходит в состояние ожидания до тех пор, пока место не освободится.

В случае неблокируемого сокета TCP при недостатке места в буфере отправки завершение происходит немедленно с ошибкой EWOULDBLOCK. Если в буфере отправки сокета есть место, возвращаемое значение будет представлять количество байтов, которое ядро смогло скопировать в буфер (это называется частичным копированием — short count).

В разделе 2.9 мы также сказали, что на самом деле буфера отправки UDP не существует. Ядро только копирует данные приложения и перемещает их вниз по стеку, добавляя к данным заголовки UDP и IP. Следовательно, операция вывода на блокируемом сокете UDP (каким он является по умолчанию) никогда не заблокируется.

3. Прием входящих соединений: функция accept. Если функция accept вызывается для блокируемого сокета и новое соединение недоступно, процесс переводится в состояние ожидания.

Если функция accept вызывается для неблокируемого сокета и новое соединение недоступно, возвращается ошибка EWOULDBLOCK.

4. Инициирование исходящих соединений: функция connect для TCP. (Вспомните, что функция connect может использоваться с UDP, но она не вызывает создания «реального» соединения — она лишь заставляет ядро сохранить IP-адрес и номер порта собеседника.) В разделе 2.5 мы показали, что установление соединения TCP включает трехэтапное рукопожатие и что функция connect не возвращает управление, пока клиент не получит сегмент ACK или SYN. Это значит, что функция TCP connect всегда блокирует вызывающий процесс как минимум на время обращения (RTT) к серверу.

Если функция connect вызывается для неблокируемого сокета TCP и соединение не может быть установлено немедленно, инициируется установление соединения (например, отправляется первый пакет трехэтапного рукопожатия TCP), но возвращается ошибка EINPROGRESS. Обратите внимание, что эта ошибка отличается от ошибки, возвращаемой в первых трех сценариях. Также отметим, что некоторые соединения могут быть установлены немедленно, когда сервер находится на том же узле, что и клиент, поэтому даже в случае неблокируемого вызова функции connect мы должны быть готовы к тому, что она успешно выполнится. Пример неблокируемой функции connect мы покажем в разделе 16.3.

ПРИМЕЧАНИЕ

Традиционно System V возвращала для неблокируемой операции ввода-вывода, которую невозможно выполнить, ошибку EAGAIN, в то время как Беркли-реализации возвращали ошибку EWOULDBLOCK. Еще больше дело запутывается тем, что согласно POSIX.1 используется EAGAIN, в то время как в POSIX.1g определено, что используется EWOULDBLOCK. К счастью, большинство систем (включая SVR4 и 4.4BSD) определяют один и тот же код для этих двух ошибок (проверьте свой системный заголовочный файл <sys/errno.h>), поэтому не важно, какой из них использовать. В нашем тексте мы используем ошибку EWOULDBLOCK, как определяется в POSIX.

В разделе 6.2 мы представили различные модели ввода-вывода и сравнили неблокируемый ввод-вывод с другими моделями. В этой главе мы покажем примеры четырех типов операций и разработаем новый тип клиента, аналогичный веб-клиенту, инициирующий одновременно множество соединений TCP при помощи неблокируемой функции connect.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Ввод/Вывод

Из книги Давайте создадим компилятор! автора Креншоу Джек


Ввод/вывод

Из книги Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT автора Фролов Александр Вячеславович

Ввод/вывод Как вы знаете, операторы << и >> выполняют сдвиг числового значения влево и вправо на опеределенное число бит. В программах, приведенных в нашей книге, эти операторы также используются для ввода информации с клавиатуры и вывода на экран.Если с левой стороны


Ввод и вывод

Из книги Основы объектно-ориентированного программирования автора Мейер Бертран

Ввод и вывод Два класса библиотеки KERNEL обеспечивают основные средства ввода и вывода: FILE и STD_FILES.Среди операций, определенных для объекта f типа FILE, есть следующие:create f.make ("name") -- Связывает f с файлом по имени name.f.open_write -- Открытие f для записиf.open_read -- Открытие f для


ГЛАВА 14 Асинхронный ввод/вывод и порты завершения

Из книги Системное программирование в среде Windows автора Харт Джонсон М

ГЛАВА 14 Асинхронный ввод/вывод и порты завершения Операциям ввода и вывода присуща более медленная скорость выполнения по сравнению с другими видами обработки. Причиной такого замедления являются следующие факторы:• Задержки, обусловленные затратами времени на поиск


Глава 10. Ввод/вывод и хранение данных

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

Глава 10. Ввод/вывод и хранение данных На чистом диске можно искать бесконечно. Томас Б. Стил младший Вычислительные машины хороши для вычислений. В этой тавтологии больше смысла, чем кажется на первый взгляд. Если бы программа только потребляла процессорное время да


Глава 6 Ввод и вывод

Из книги Программирование на языке Пролог для искусственного интеллекта автора Братко Иван

Глава 6 Ввод и вывод В этой главе мы рассмотрим некоторые встроенные средства для записи данных в файл и считывания их из файла. Такие средства можно также применять и для форматирования объектов данных программы, чтобы получить желаемую форму их внешнего представления.


Ввод и вывод

Из книги Язык программирования Си для персонального компьютера автора Бочков C. О.

Ввод и вывод Функции ввода и вывода в стандартной библиотеке Си позволяют читать данные из файлов или получать их с устройств ввода (например, с клавиатуры) и записывать данные в файлы, или выводить их на различные устройства (например, на принтер).Функции ввода/вывода


Глава 4 Файлы и файловый ввод/вывод

Из книги Linux программирование в примерах автора Роббинс Арнольд

Глава 4 Файлы и файловый ввод/вывод Данная глава описывает базовые файловые операции: открытие и создание файлов, чтение и запись в них, перемещение в них и их закрытие. По ходу дела она представляет стандартные механизмы для обнаружения ошибок и сообщений о них. Глава


4.4. Ввод и вывод

Из книги Основы программирования на Java автора Сухов С. А.

4.4. Ввод и вывод Все операции Linux по вводу/выводу осуществляются посредством дескрипторов файлов. Данный раздел знакомит с дескрипторами файлов, описывает, как их получать и освобождать, и объясняет, как выполнять с их помощью


1.5.1. Файловый ввод/вывод

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

1.5.1. Файловый ввод/вывод Библиотека iostream поддерживает и файловый ввод/вывод. Все операции, применимые в стандартному вводу и выводу, могут быть также применены к файлам. Чтобы использовать файл для ввода или вывода, мы должны включить еще один заголовочный файл:#include


Глава 25 Управляемый сигналом ввод-вывод

Из книги QT 4: программирование GUI на С++ автора Бланшет Жасмин

Глава 25 Управляемый сигналом ввод-вывод 25.1. Введение Ввод-вывод, управляемый сигналом, подразумевает, что мы указываем ядру проинформировать нас сигналом, если что-либо произойдет с дескриптором. Исторически такой ввод-вывод назвали асинхронным вводом-выводом, но в


Глава 12. Ввод—вывод

Из книги Идеальный программист. Как стать профессионалом разработки ПО автора Мартин Роберт С.

Глава 12. Ввод—вывод Почти в каждом приложении приходится читать или записывать файлы или выполнять другие операции ввода—вывода. Qt обеспечивает великолепную поддержку ввода—вывода при помощи QIODevice — мощной абстракции «устройств», способных читать и записывать


Ввод и вывод

Из книги автора

Ввод и вывод Также мне кажется очень важным, чтобы мои результаты подпитывались соответствующим «вводом». Написание программного кода – творческая работа. Обычно мои творческие способности в наибольшей степени проявляются тогда, когда я сталкиваюсь с творческим