Aparment Analogy от Microsoft (STA, MTA): нужна помощь в понимании - PullRequest
2 голосов
/ 26 января 2012

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

Microsoft использует аналогию живых существ, живущих в квартире.Итак, для STA рассмотрим следующее (я знаю, что это немного глупо).

  1. Предположим, что thread = person и COMObject = бактерии.Человек живет в квартире, а бактерии живут внутри человека.Таким образом, в STA-Land поток проживает в STA, а COMObject живет внутри потока, поэтому для взаимодействия с COMObject необходимо выполнить код в потоке COMObject.

  2. Предположим, что thread = person и COMObject = cat.Человек живет в квартире, а кот живет в квартире с человеком.SO в STA-Land, поток и COMObject на одном иерархическом уровне.

Q1.Какая приведенная выше аналогия верна, или если ни одна из них не верна, как бы вы описали STA?

Q2.Как бы вы описали MTA?

Ответы [ 2 ]

3 голосов
/ 26 января 2012

Это не очень хороший термин. Это фактически описывает поток поведение . Поток сообщает COM, как он ведет себя в вызове CoInitializeEx (), выбирая между STA и MTA. Используя STA, поток обещает , что он ведет себя таким образом, который подходит для кода, который не является потокобезопасным. Твердые обещания, которые он дает:

  • Никогда не блокирует выполнение
  • Прокачивает цикл сообщений

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

Это имеет значение в первую очередь, когда создается COM-объект. Такой объект содержит ключ в реестре, который описывает, какую безопасность потоков он реализует. Ключ ThreadingModel. На сегодняшний день наиболее распространенным значением для этого ключа является «Квартира» (или оно отсутствует), сообщающее COM, что оно вообще не поддерживает многопоточность и что любые вызовы объекта должны выполняться из одного потока.

Если поток, который создает такой объект, находится в STA, то все устраивает. В конце концов, поток обещал поддерживать однопоточные объекты. Если поток находится в MTA, то есть проблема, поток сказал, что он не поддерживает безопасность потока, но все же создал объект, который не является потокобезопасным. COM добавляет в поток новый поток STA, который может поддерживать код, который не является потокобезопасным. Код получает прокси к объекту. Любые звонки, сделанные на объекте, проходят через этот прокси. Прокси-код перехватывает вызов и запускает его в созданном потоке STA, обеспечивая тем самым вызов в поточно-ориентированном виде.

Как вы можете себе представить, работа, выполняемая прокси-сервером, недешевая. Он включает в себя два переключателя контекста потока, и для выполнения вызова должен быть создан стек стека из аргументов функции. Он также должен ждать, пока поток не будет готов выполнить вызов. Это называется маршалинг , это на 3 порядка медленнее, чем звонить без маршалинга. Возможно, это также объясняет причину, по которой поток STA имеет эти два требования, перечисленные выше. Он не может блокировать, потому что, пока он блокирует этот маршализованный вызов, он не может быть выполнен и очень вероятно возникновение тупика. И он должен прокачивать цикл сообщений, что делает возможным ввод вызова в другой поток.

Так что присоединение к MTA - это простое программирование для вас. Но смертельно для производительности. STA эффективен .

3 голосов
/ 26 января 2012

Мне не нравятся эти аналогии. Они сбивают с толку.

Вы создаете квартиру.

Если это STA, в квартире будет только один поток, поэтому все объекты в этой квартире будут выполняться в этом отдельном потоке (поэтому одновременное выполнение объектов в этой квартире не выполняется)

Если это MTA, в этой квартире может быть несколько потоков. Таким образом, объекты в MTA должны реализовывать синхронизацию явно, если это необходимо.

Объект живет в одной квартире. В одной квартире может быть несколько объектов.

Очень хорошее прочтение здесь

...