Похожие презентации:
Tema_11_Async_IO
1.
ТЕМА 11Асинхронная
обработка
данных
Концепция асинхронного ввода-вывода
и порты завершения
Операционные системы
01
2.
Работа продолжается во время ожиданияЗапрос сейчас.
Результат позже.
1 Запуск операции
Приложение передаёт
дескриптор, буфер и контекст.
2 ОС выполняет запрос
Асинхронный ввод-вывод позволяет запустить
операцию и получить её результат отдельно
от вызова, который её начал.
Поток может обрабатывать
другую работу.
3 Приходит завершение
Приложение проверяет статус и
использует данные.
02
3.
Три модели ввода-выводаМодель
Что получает вызывающий поток
Как продолжить работу
Блокирующая
Ждёт результат внутри вызова
После возврата из read /
ReadFile
Неблокирующая
Быстрый ответ: данные или «пока
нет»
Ждать готовности и повторить
попытку
Асинхронная
Статус запуска операции
Получить уведомление о её
завершении
Готовность к I/O отличается от завершения операции.
03
4.
Перекрытие ожидания и вычисленийУчебный пример: I/O занимает 100 мс, независимые вычисления — 20 мс.
120 мс
120
Время, мс
Последовательно
С перекрытием
100
100 + 20
≈ 100 мс
max(100, 20)
Условия: работа независима, перекрытие возможно, накладные расходы не учитываются.
04
5.
Как приложение узнаёт о завершенииМеханизм
Как устроено уведомление
Где полезен
Событие (event)
ОС сигнализирует объект события
Небольшое число ожидаемых
операций
Completion routine
Callback при alertable wait
Последовательность в
заданном потоке
Опрос результата
Программа сама проверяет состояние
Когда частота проверки
оправдана
Порт завершения
IOCP
Пакеты завершений в общей очереди
Много операций и рабочие
потоки
05
6.
OVERLAPPED: контекст одной операцииДескриптор
Файл открывают с
FILE_FLAG_OVERLAPPED.
Для каждой активной операции создают
отдельный контекст.
struct Request {
OVERLAPPED ov{};
char buffer[4096];
// данные запроса
};
OVERLAPPED
Буфер и контекст
Смещение в файле, служебные поля и
необязательный hEvent.
Живут до подтверждённого завершения
операции.
06
7.
Три результата запуска ReadFileВозврат ReadFile
Значение
Действие приложения
TRUE
Операция завершилась сразу
При обычном IOCP ждать пакет
завершения
FALSE +
ERROR_IO_PENDING
Операция принята и ещё
выполняется
Сохранить буфер и контекст,
ждать завершения
FALSE +
другая ошибка
Запуск не принят либо вернул
ошибку
Обработать код ошибки запуска
ERROR_IO_PENDING — штатный статус асинхронного запроса.
07
8.
Порт завершения ввода-выводаIOCP
I/O Completion Port
Объект ядра Windows с очередью
пакетов завершения и механизмом
пробуждения рабочих потоков.
01
Дескрипторы
Файлы, сокеты и каналы связаны с
портом.
02
Операции
Приложение запускает overlapped I/O.
03
Очередь завершений
ОС добавляет сведения о
результатах.
04
Рабочие потоки
Извлекают пакеты и продолжают
обработку.
08
9.
Основные API WindowsЭтап
Функция
Назначение
Создание и привязка
CreateIoCompletionPort
Создать порт и связать с ним
дескриптор
Запуск I/O
ReadFile / WriteFile
WSARecv / WSASend
Передать запрос вместе с
OVERLAPPED
Получение результата
GetQueuedCompletionStatus
Извлечь очередной пакет
завершения
Служебные сообщения
PostQueuedCompletionStatus
Добавить собственный пакет в
очередь
09
10.
Содержимое пакета завершенияПоле результата
Что позволяет узнать
Число переданных байтов
Сколько данных фактически обработала операция
CompletionKey
К какому дескриптору или соединению относится
результат
OVERLAPPED*
Какая именно операция завершилась
Статус операции
Успех либо код ошибки после возврата функции
Ключ описывает дескриптор. OVERLAPPED различает запросы к нему.
10
11.
Рабочие потоки и конкурентностьМного запросов
ожидают I/O
Ограниченное число
потоков
обрабатывает
завершения
Предел конкурентности
Короткие обработчики
IOCP ограничивает число одновременно
работающих потоков, связанных с портом.
Долгие вычисления и блокирующие
вызовы задерживают обработку
следующих пакетов.
11
12.
Пример: запуск чтения с IOCPauto* req = new Request{};
BOOL ok = ReadFile(file, req->buffer,
sizeof(req->buffer), nullptr, &req->ov);
if (!ok) {
DWORD err = GetLastError();
if (err != ERROR_IO_PENDING) {
report_error(err);
delete req; // запрос не принят
}
}
// TRUE или PENDING: req обработает рабочий поток IOCP.
Фрагмент C++: файл уже связан с IOCP, уведомления о завершении включены.
12
13.
Пример: получение завершенияDWORD bytes = 0;
ULONG_PTR key = 0;
OVERLAPPED* ov = nullptr;
BOOL ok = GetQueuedCompletionStatus(
port, &bytes, &key, &ov, INFINITE);
DWORD err = ok ? ERROR_SUCCESS : GetLastError();
if (ov != nullptr) {
finish_request(ov, bytes, key, err);
} else if (!ok) {
handle_wait_error(err); // key и bytes не читать
} else {
handle_control_packet(key);
}
FALSE + ov ≠ nullptr: операция завершилась с ошибкой, и её контекст нужно обработать.
13
14.
Срок жизни запроса и отмена1
Создание
Буфер и OVERLAPPED готовы до запуска.
2
Выполнение
Приложение сохраняет контекст и не меняет буфер.
3
Отмена
Если нужна отмена, приложение вызывает CancelIoEx.
4
Подтверждение
Приложение получает итоговое завершение.
5
Освобождение
После обработки результата ресурсы можно вернуть.
CancelIoEx не дожидается завершения отмены.
14
15.
Ограничение нагрузки и памятьN×B
Активные запросы × размер буфера
10 000 × 64 КиБ ≈ 625 МиБ
Только буферы, без контекстов и памяти ОС.
Расчётный пример, не измерение.
Лимит активных операций
При достижении лимита
приложение приостанавливает
новые запросы.
Контроль очередей
Backpressure согласует скорость
поступления и обработки данных.
Измерение результата
Время ответа, скорость обработки,
память и загрузка CPU.
15
16.
Сценарий: сетевой сервер01
Сервер размещает WSARecv для соединения.
02
Пока данные идут по сети, поток свободен.
03
IOCP сообщает о завершении приёма.
04
Обработчик разбирает данные и формирует
ответ.
05
WSASend запускает отправку ответа.
16
17.
Windows и Linux: готовность и завершениеМеханизм
Событие
Что делает приложение
Windows IOCP
Операция завершилась
Извлекает пакет и обрабатывает
результат
Linux epoll
Дескриптор готов к
операции
Пробует неблокирующее чтение
или запись
Linux io_uring
Результат отправленного
запроса
Получает CQE из очереди
завершений
epoll обычно связывают с Reactor, IOCP и io_uring — с моделью завершений.
17
18.
Ошибки, которые нарушают работу I/OОшибка
Последствие
Правильный подход
Освободить буфер после
запуска
Обращение к уже
освобождённой памяти
Дождаться итогового
завершения
Переиспользовать
OVERLAPPED
Смешение контекстов
запросов
Отдельная структура на
активную операцию
Обработать TRUE дважды
Повторная обработка или
освобождение
Один согласованный путь
завершения
Ожидать порядок запуска
Неверное состояние
приложения
Учитывать независимый
порядок завершений
18
19.
Главные выводы и самопроверкаАсинхронность
Разделяет запуск I/O и получение
результата.
IOCP
Объединяет завершения многих
запросов в одну очередь.
Объясните своими
словами
1. Почему ERROR_IO_PENDING
не означает сбой?
2. Чем готовность отличается
от завершения?
3. Когда можно освободить
буфер после CancelIoEx?
Надёжность зависит от управления
контекстами, буферами и нагрузкой.
19
20.
Источники для изучения01
Microsoft Learn
Synchronous and Asynchronous I/O
02
Microsoft Learn
I/O Completion Ports
03
Microsoft Learn
ReadFile и OVERLAPPED
04
Microsoft Learn
GetQueuedCompletionStatus и CancelIoEx
05
Linux man-pages
epoll(7)
06
Linux man-pages
io_uring(7)
Названия источников кликабельны. Точные ссылки к темам приведены в заметках слайдов.
20