Обратные вызовы в C++ | страница 7



1.3.2. Контекст

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

Однако такая ситуация встречается далеко не всегда, в большинстве случаев требуется знать значения переменных, внешних по отношению к функции исполнителя. Другими словами, необходимо получить контекст вызова.

Важность контекста можно проиллюстрировать на следующем примере. Пусть мы реализуем подсистему сетевого обмена, которая осуществляет передачу данных по каналам связи. Для управления каналом создается отдельный класс, задачей которого является формирование и отправка пакетов через вызовы соответствующих функций операционной системы. Операционная система, в свою очередь, подтверждает о доставке пакета через обратный вызов (Рис. 8). Как нам узнать в коде обработчика вызова, для какого класса предназначено подтверждение? Здесь-то и необходим контекст вызова, в качестве которого выступает указатель на класс, управляющий нужным каналом. Этот указатель не хранится внутри кода обработчика, он должен каким-то образом ему передаваться. Другими словами, обработчик вызова должен получить контекст. Различные реализации обратных вызовов предлагают свои собственные способы передачи и интерпретации контекста, которые будут подробно рассматриваться в соответствующих главах.


Рис. 8. Сетевой обмен и контекст вызова


1.4. Архитектурный дизайн вызовов

1.4.1. Синхронные и асинхронные вызовы

C точки зрения архитектурного дизайна обратные вызовы можно разделить на синхронные и асинхронные. Если при вызове какой-либо функции инициатора обратный вызов происходит внутри тела этой функции, которая затем возвращает управление, то вызов является синхронным (другое название – блокирующий). Если обратный вызов может произойти в любое время, то этот вызов является асинхронным (другое название – отложенный).

Синхронный вызов – архитектурный дизайн, в котором при вызове функции инициатора обратный вызов происходит до выхода из тела этой функции.

Асинхронный вызов – архитектурный дизайн, в котором обратный вызов может быть выполнен в любое время.

Различие между синхронными и асинхронными вызовами проиллюстрировано на Рис. 9. В первом случае поток управления входит в функцию