COM-подсчет ссылок - безопасность потоков - PullRequest
3 голосов
/ 24 апреля 2011

Если у меня есть COM-объект, требуется ли, чтобы методы AddRef () и Release () были поточно-ориентированными, т. Е. Чтобы мне приходилось использовать атомарные операции для подсчета ссылок?

Ответы [ 4 ]

3 голосов
/ 24 апреля 2011

Да, если вы используете модель бесплатной многопоточной конфигурации, используйте InterlockedIncrement () и InterlockedDecrement () для обработки количества ссылок.

3 голосов
/ 24 апреля 2011

Я думаю, что ответ - нет.Это не требуется .Если вы хотите, чтобы ваш COM-объект был потокобезопасным, тогда он должен быть потокобезопасным.В противном случае они не должны быть.

Например, если вы посмотрите здесь: Правила объектной модели компонентов , это не упоминается как требование.Также Поваренная книга программиста COM (Создание компонента COM), вы можете увидеть образец объекта без потокового безопасного подсчета ссылок.

Фрагмент кода Microsoft:

ULONG COutside::AddRef (void)
{
    return ++ m_cRef;
}

На практикебольшинство реализаций сделали бы это, потому что в противном случае COM-объекты не были бы поточно-ориентированными.Если вы знаете, что объект будет использоваться только в одном потоке, я считаю, что это разрешенная оптимизация.Не все COM-объекты являются поточно-ориентированными, я работал с некоторыми, которые не были такими.

Чтобы справиться с тем фактом, что COM-объекты могут быть или не могут быть поточно-безопасными, COM предлагает разные «квартиры», в которых COMобъекты созданы.В однопоточной квартире только один поток может получить доступ к объектам в этой квартире, тогда как в многопоточной квартире объекты могут совместно использоваться несколькими потоками.Цитата из Понимание и использование потоковых моделей COM :

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

1 голос
/ 25 апреля 2011

Это будет зависеть от используемой модели потоков и типа объекта.Пожалуйста, смотрите описание _ATL_*_THREADED макросов .Эти макросы влияют на потокобезопасность AddRef()/Release() «обычных» классов и фабрик.

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

Вот как вы выбираете правильный макрос (и это объясняет, является ли AddRef()/Release() должен быть потокобезопасным).

Если во всех классах одного сервера не указана модель потоков (Main STA), то нет возможности одновременного доступа к объектам или фабрикам, и все они могут иметь не-threadsafe AddRef()/Release(), и вы получите это, указав макрос _ATL_SINGLE_THREADED.

В противном случае, если хотя бы в одном классе указана модель "Квартира", вам необходимо поточно-ориентированное AddRef()/Release() для фабрики этого объекта, но все жеможет иметь не-потокобезопасный AddRef()/Release() в самом объекте, и вы получите это, указав макрос _ATL_APARTMENT_THREADED.Этот макрос заставит все фабрики иметь потокобезопасный AddRef()/Release() и весь объект - не-потокобезопасный AddRef()/Release().

Наконец, если хотя бы в одном классе указана нужная вам модель потоков «Оба» или «Свободная» AddRef()/Release(), чтобы быть потокобезопасным как в этом классе, так и на фабрике, и вы должны либо указать _ATL_FREE_THREADED, либо просто не указывать ничего из вышеперечисленного - этот «наиболее узкий» макроэффект будет включен по умолчанию.Поэтому конфигурация по умолчанию для COM-объектов, созданных с использованием ATL, должна иметь поточно-ориентированный AddRef()/Release() для всех объектов - как обслуживаемых объектов, так и фабрик.

При этом вам не всегда нужно, чтобы AddRef()/Release() был поточным.безопасно, но обычно вам следует делать это, если вы точно не знаете, что можете обойтись без него, а что без него позволяет повысить производительность.

1 голос
/ 24 апреля 2011

Да.Это требуется.COM - это простой двоичный стандарт, и если вы используете Free Threaded Apartments, вы получите по-настоящему бесплатный многопоточный доступ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...