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

на главную

Жанры

Интернет-журнал "Домашняя лаборатория", 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 апартамента, то этот объект будет создан в этом же апартаменте. И согласно правилам СОМ потоки из всех других апартаментов должны обращаться к данному объекту только через прокси. На самом деле, они могли бы обращаться к нему, используя прямой указатель, т. к. этот объект сможет правильно обработать все вызовы, не зависимо от апартамента, из которого они были сделаны.

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

Архил...?

Кожевников Павел
1. Архил...?
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Архил...?

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Жребий некроманта 2

Решетов Евгений Валерьевич
2. Жребий некроманта
Фантастика:
боевая фантастика
6.87
рейтинг книги
Жребий некроманта 2

Совершенный: пробуждение

Vector
1. Совершенный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Совершенный: пробуждение

Два лика Ирэн

Ром Полина
Любовные романы:
любовно-фантастические романы
6.08
рейтинг книги
Два лика Ирэн

Мимик нового Мира 6

Северный Лис
5. Мимик!
Фантастика:
юмористическая фантастика
попаданцы
рпг
5.00
рейтинг книги
Мимик нового Мира 6

Табу на вожделение. Мечта профессора

Сладкова Людмила Викторовна
4. Яд первой любви
Любовные романы:
современные любовные романы
5.58
рейтинг книги
Табу на вожделение. Мечта профессора

Пожиратель душ. Том 1, Том 2

Дорничев Дмитрий
1. Демон
Фантастика:
боевая фантастика
юмористическая фантастика
альтернативная история
5.90
рейтинг книги
Пожиратель душ. Том 1, Том 2

Тринадцатый II

NikL
2. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый II

Сумеречный Стрелок 4

Карелин Сергей Витальевич
4. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 4

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Все ведьмы – стервы, или Ректору больше (не) наливать

Цвик Катерина Александровна
1. Все ведьмы - стервы
Фантастика:
юмористическая фантастика
5.00
рейтинг книги
Все ведьмы – стервы, или Ректору больше (не) наливать

Изгой. Пенталогия

Михайлов Дем Алексеевич
Изгой
Фантастика:
фэнтези
9.01
рейтинг книги
Изгой. Пенталогия

Провинциал. Книга 2

Лопарев Игорь Викторович
2. Провинциал
Фантастика:
космическая фантастика
рпг
аниме
5.00
рейтинг книги
Провинциал. Книга 2