Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции.doc
Скачиваний:
16
Добавлен:
20.06.2014
Размер:
523.26 Кб
Скачать

Активные объекты с множественными рабочими потоками

Количество рабочих потоков определяется в проекте активного объекта с учетом согласования скоростей генерации запросов и их обработки. Цикл выборки заданий работает с определенным количеством операций, заполняя промежуточный кратковременный буфер, затем вызывая диспетчер, который создает рабочие потоки, анализируя состояние этого буфера. Затем начинает работу цикл сбора результатов, который ожидает завершения работы потоков, также предоставляя им промежуточный буфер. Затем все собранные результаты помещаются в одну выходную очередь, в которую помещаются все клиентские заглушки асинхронного получения результатов. Объекты, устроенные по такой схеме, имеют в среднем N +1 активный поток, т.к. помимо рабочих функций есть еще поток диспетчеризации работы.

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

Пулы активных объектов

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

Маршалинг и сериализация

Этим термином обозначается процедура, предназначенная для передачи всей необходимой для вызова информации посредством «плоских» буферов и каналов связи.

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

Как правило, рассматриваются два типа маршалинга:

  1. Маршалинг документов стандартных типов;

  2. Пользовательский маршалинг.

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

- строка, завершающаяся нулем;

- строка, снабженная длиной;

- строка, снабженная длиной и завершающаяся нулевым символом.

Составные типы, формируемые как структуры или одномерные массивы из перечисленных компонентов также могут подвергаться автоматическому маршалингу.

Для возможности стандартизации маршалинга в рамках системы необходимо определить декларативный язык описания данных, который позволял бы однозначно установить:

  1. Длину в байтах любого компонента;

  2. Byte order (порядок байт);

  3. Выравнивание.

Одним из удобных средств описания данных является язык XML (расширяемый язык разметки), который позволяет формировать иерархические структуры, например:

<mydata>

<int>

12

<\int>

<float>

1.5

<\float>

<\mydata>

Помимо ХML можно использовать двоичный формат в тех случаях, когда маршалинг требует осуществления с высокой производительностью и низкими расходами памяти. В этих случаях используется формат стекового кадра, который без изменения копируется на удаленную сторону. Недостаток – работоспособность только на строго определенной архитектуре.

При этом используют следующий алгоритм: процедуру, предназначенную для удаления вызова, снабжают преамбулой, задача которой сводится к определению участка стека, занятого аргументами вызова. Преамбула копирует участок в буфер и передает в определенную сторону. Та часть процедуры, которая запускается на удаленной стороне, в качестве преамбулы выполняет обратные действия, копируя буфер определенного размера без изменения в стек и дальше приступая к выполнению основного алгоритма. Как правило преамбулы (заглушки) автоматически генерируются по декларативным описаниям.

Для динамических структур данных, содержащих указатели, требуется маршалинг в соответствии с принципом глубокого копирования (примеры: деревья, стеки и т.п.).

Для таких структур данных критическим является отсутствие в них циклической зависимости.

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

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

  1. Работающая на вызывающей стороне.

  2. Работающая на вызываемой стороне.

(авторам структуры данных, специфичной для задач)

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

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

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

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

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

Примеры организации очередей сообщений в ОС Windows

Каждый поток в ОС Windows создается без очереди сообщений, т.к. накладные расходы на ее организацию достаточно велики, а передача и обработка сообщений требуется не всем потокам. В то же время прозрачна для программиста система автоматического создания системных сообщений при вызове потоком любой функции API, которая не работоспособна без очереди сообщений.

Фактически создается несколько очередей, основные из которых – очереди синхронных (posted) и асинхронных (sent) сообщений.

Посылка асинхронных сообщений в очередь потока

BOOL PostMessage (HWND hwnd,

UINT uMsg,

WPARAM wParam,

LPARAM lParam);

hwnd – дескриптор окна

uMsg – код сообщения

wParam, lParam – дополнительные параметры

Данная функция посылает асинхронное сообщение в очередь того потока, который создал окна с дескриптором hwnd, uMsg задает код сообщения, а wParam и lParam – дополнительные параметры. Архитектура Windows предполагает, что всегда есть соответствие поток – окно, поэтому передача сообщений всегда возможна. Система самостоятельно выделяет участок памяти, копирует в него код, параметры сообщения и другую информацию, относящуюся к данной посылке. Возврат из этой функции происходит немедленно, так что никакой информации о результатах обработки вызывающая сторона не получит. Возвращенное значение свидетельствует только о доставке сообщения и об отсутствии системных ошибок в этой ситуации.

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

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

BOOL PostThreadMessage (DWORD dwIbreadID,

UINT uMsg,

WPARAM wParam,

LPARAM lParam);

Данная функция посылает сообщение в очередь потока с указанием идентификатора. Остальная информация аналогична PostMessage. Поскольку система исполняет одну и ту же структуру информации блока сообщения, то при вызове данной функции в поле дескриптора окна адресата значится. Автоматическая диспетчеризация процедуры обработки в данном случае невозможна, поскольку регистрируемая функция обработки сообщений относится к окнам, а не к потокам.

void PostQuit Message (int exitCode);

Очередь сообщений содержит флажок – признак того, что к ней обратились с функцией PostQuit Message. Функция выборки сообщений возвращает ноль в этом случае, и приложение имеет возможность завершить цикл выборки сообщений.

Соседние файлы в предмете Системное программное обеспечение