Чтение онлайн

на главную - закладки

Жанры

Интернет-журнал "Домашняя лаборатория", 2007 №6
Шрифт:

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

В случае STA

поток имеет прямой указатель на некоторый интерфейс объекта (т. к. именно этот поток и создал этот объект) и может делать прямые вызовы его методов.

В случае МТА

? либо данный поток создал данный объект и, следовательно, имеет на него прямой указатель,

? либо объект создан каким-то другим потоком из МТА.

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

глобальной переменной. Все остальные потоки из МТА (и только из МТА!) могут использовать этот указатель для прямого вызова методов данного интерфейса.

Напрямую можно обращаться и к объектам из NA, независимо от того, поток из какого апартамента создал этот объект. Эта новая технология появилась в Windows 2000. Рекомендуется все вновь создаваемые СОМ+ объекты создавать для размещения их в NA. Преимуществом данной технологии является отсутствие переключения потоков. Вызывающий поток независимо от апартамента покидает свой апартамент и выполняет код метода объекта из NA. В данном разделе мы более не будем обсуждать эти новые возможности и продолжим изучать проблемы, связанные с классическими STA и МТА.

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

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

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

Здесь уместно заметить, что прокси и стаб должны быть зарегистрированы в реестре как поддерживающие потоковую модель Both. Это позволит загружать прокси и стаб в любой апартамент. Такая регистрация выполняется автоматически, если используется idl для описания интерфейсов и компилятор MIDL.

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

Данный поток сам инициировал порождение данного объекта

В этом случае автоматически выполняется маршалинг запрошенного интерфейса, который сводится к получению некоторого нейтрального к апартаменту представления указателя на интерфейс, передачи его в апартамент вызывающего потока и к построению (с помощью proxy/stab DLL, которая должна быть построена для данного сервера и зарегистрирована на данной машине) прокси в вызывающем апартаменте и стаба в вызываемом апартаменте. Таким образом, вызывающий поток получает указатель на прокси, имитирующий для него объект из другого апартамента. Если в данном апартаменте кроме вызывающего потока имеются другие потоки (случай МТА), то и эти другие потоки могут использовать построенный указатель на прокси.

Данный поток не инициировал порождение данного объекта

В этом

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

Процедура состоит из двух шагов

? Маршализация указателя на интерфейс

Поток из апартамента, в котором живет интересующий нас объект, формирует нейтральное относительно апартамента представление указателя на интерфейс.

Для этого вызывается функция библиотеки СОМ

? WINOLEAPI CoMarshallnterThreadlnterfacelnStream(

? [in] REFIID riid,

? [in] LPUNKNOWN pUnk,

? [out] LPSTREAM *ppStm);

В данную функцию передаются сылка на GUID интерфейса и указатель на этот интерфейс. В качестве результата получаем указатель на доступный для обоих потоков объект-поток (stream object), который поддерживает стандартный интерфейс istream и используется для временного хранения нейтрального представления указателя на запрошенный интерфейс.

? Демаршализация указателя на интерфейс

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

? WINOLEAPI CoGetlnterfaceAndReleaseStream(

? [in] LPSTREAM pStm,

? [in] REFIID riid,

? [out] LPVOID FAR* ppv);

Выходной параметр дает указатель на желаемый интерфейс, который на самом деле является указателем на прокси, через который поток может делать вызов через границу между апартаментами. Как и при автоматическом маршалинге интерфейсов здесь используется proxy/stab DLL, содержащая код маршалинга для интересующего нас интерфейса.

Заметим, что описанный прием можно применить и в том случае, когда вызывающий поток и вызываемый объект находятся в одном апартаменте, но никто в данном апартаменте не имеет прямого указателя на этот объект. Такая ситуация может возникнуть, например, когда поток из STA создает объект с потоковой моделью Free, а потом некоторый поток из МТА желает вызвать метод этого объекта. В этом случае никто в МТА не имеет прямого указателя на построенный объект. Только поток в STA имеет указатель на прокси для этого объекта. Необходимо выполнить маршализацию указателя на интерфейс в STA и его демаршализацию в МТА. Система сама обнаружит, что вызывающий поток и вызываемый объект находятся в одном апартаменте и вместо прокси предоставит прямой указатель на объект.

Описанный способ маршалинга указателя на интерфейс имеет определенные недостатки:

Неоптимальность вызова объекта с потоковой моделью Both

Объект с потоковой моделью Both столь безопасен, что может жить в апартаменте любого типа совместно с объектами любого типа. Если, например, такой объект был создан потоком из некоторого STA апартамента, то этот объект будет создан в этом же апартаменте. И согласно правилам СОМ потоки из всех других апартаментов должны обращаться к данному объекту только через прокси. На самом деле, они могли бы обращаться к нему, используя прямой указатель, т. к. этот объект сможет правильно обработать все вызовы, не зависимо от апартамента, из которого они были сделаны.

Поделиться:
Популярные книги

Record of Long yu Feng saga(DxD)

Димитров Роман Иванович
Фантастика:
фэнтези
5.00
рейтинг книги
Record of Long yu Feng saga(DxD)

Вусмиор. По ту сторону барьера

Глакс М. О.
7. Легенды Верхнего Мира
Фантастика:
городское фэнтези
фэнтези
5.00
рейтинг книги
Вусмиор. По ту сторону барьера

Мастер 9

Чащин Валерий
9. Мастер
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер 9

Шаман. Ключи от дома

Калбазов Константин Георгиевич
2. Шаман
Фантастика:
боевая фантастика
7.00
рейтинг книги
Шаман. Ключи от дома

Начальник милиции. Книга 6

Дамиров Рафаэль
6. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 6

Вы не прошли собеседование

Олешкевич Надежда
1. Укротить миллионера
Любовные романы:
короткие любовные романы
5.00
рейтинг книги
Вы не прошли собеседование

Попаданка

Ахминеева Нина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Попаданка

Гладиатор по крови

Скэрроу Саймон
9. Орел
Приключения:
исторические приключения
7.78
рейтинг книги
Гладиатор по крови

Красная королева

Ром Полина
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Красная королева

Чужая семья генерала драконов

Лунёва Мария
6. Генералы драконов
Фантастика:
фэнтези
5.00
рейтинг книги
Чужая семья генерала драконов

Боярышня Евдокия

Меллер Юлия Викторовна
3. Боярышня
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Боярышня Евдокия

Санек

Седой Василий
1. Санек
Фантастика:
попаданцы
альтернативная история
4.00
рейтинг книги
Санек

Барон нарушает правила

Ренгач Евгений
3. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон нарушает правила

Третий. Том 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий. Том 4