воскресенье, 12 апреля 2009 г.

Страшная и ужасная потоковая модель "main"

Это перевод The dreaded "main" threading model. Автор: Реймонд Чен.

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

Первый поток в процессе, который инициализирует COM объявляется "главным" ("main") потоком (а может быть, это первый поток, инициализирующий COM в apartment модели - я забыл). Когда создаётся объект с моделью "main", COM маршалирует создающий вызов в главный поток, создаёт там объект, а затем маршалирует результат обратно в поток-создатель. Аналогично, когда вы вызываете любой метод объекта, вызов маршалируется в главный поток, выполняется, и его результаты маршалируются обратно.

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

Как вы можете предположить, это приводит к огромному пенальти на производительность в любом много-поточном приложении, из-за большого количества маршалинга. Даже хуже: главный поток становится бутылочным горлышком (bottleneck), потому что теперь все эти объекты должны обслуживаться именно им, а не другим потоком.

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

Тогда почему такая ужасная потоковая модель вообще существует?

Для обратной совместимости с COM-объектами, написанными до того момента, когда поддержка многопоточности была добавлена в COM. В те дни был только один поток, так что COM-объекты могли быть сколь угодно ленивыми в своей синхронизации. Фактически, им не нужна была никакая синхронизация! Если у вас был только один поток, то вам точно не нужно было координировать свои действия с другими потоками, потому что их попросту не было.

Это также объясняет, почему модель "main" является моделью по-умолчанию. Различные потоковые модели были изобретены, когда поддержка многопоточности была добавлена в COM. До этого не было никаких потоков, поэтому не было и потоковых моделей. Поэтому все старые объекты не указывали никакую модель при регистрации.

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

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

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

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