Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Модуль Forms 65535
ТЕХНОЛОГИИ ДОСТ... 63081
Имитационное мо... 58363
Реклама
Сейчас на сайте
Гостей: 7
На сайте нет зарегистрированных пользователей

Пользователей: 13,092
новичок: VinDrossel
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Диплом RSA, ЭЦП, сертификаты, шифрование на C#
Моделирование литейного цеха на GPSS + Пояснительная записка
Изменения контуров и сортировка в двумерном массиве чисел на Turbo Pasca...

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
Снова интерфейс и реализация



Некоторые разработчики всесторонне используют многопоточные программные технологии и способны написать удивительно изощренный программный продукт с использованием примитивов синхронизации потоков, доступных из операционной системы. Другие разработчики больше сконцентрированы на решении вопросов, специфических для их области, и не утруждают себя написанием нудного потоко-безопасного кода. Третьи разработчики имеют особые ограничения по организации потоков, связанные с тем, что многие системы с управлением окнами (включая Windows) имеют очень строгие правила взаимодействия потоков и оконных примитивов. Еще один класс разработчиков может широко использовать старую библиотеку классов, которая неприязненно относится к потокам и не может допустить какого бы то ни было многопоточного обращения. У всех четырех типов разработчиков должна быть возможность использования объектов друг друга без перестраивания их потоковой стратегии, чтобы приспособиться ко всем возможным сценариям. Чтобы облегчить прозрачное использование объекта безотносительно к его осведомленности о потоках, СОМ рассматривает ограничения на параллелизм объектов как еще одну деталь реализации, о которой клиенту не нужно беспокоиться. Чтобы освободить клиента от ограничений параллелизма и реентерабельности (повторной входимости), в СОМ имеется весьма формальная абстракция, которая моделирует связь объектов с процессами и потоками. Эта абстракция носит название апартамент ( apartment ) [1] . Апартаменты определяют логическое группирование объектов, имеющих общий набор ограничений по параллелизму и реентерабельности. Каждый объект СОМ принадлежит к ровно одному апартаменту: один апартамент, однако, может быть общим для многих объектов. Апартамент, к которому относится объект, безоговорочно является частью идентификационной уникальности объекта.
Апартамент не является ни процессом, ни потоком; но в то же время апартаменты обладают некоторыми свойствами обоих этих понятий. Каждый процесс, использующий СОМ, имеет один апартамент или более; тем не менее, апартамент содержится ровно в одном процессе. Это означает, что каждый процесс, использующий СОМ, имеет как минимум одну группу объектов, которая удовлетворяет требованиям параллелизма и реентерабельности; однако два объекта, находящихся в одном и том же процессе, могут принадлежать к двум различным апартаментам и поэтому иметь разные ограничения по параллелизму и реентерабельности. Этот принцип позволяет библиотекам с совершенно различными понятиями о потоках мирно соучаствовать и одном общем процессе.
Поток одновременно выполняется в одном и только одном апартаменте. Для того чтобы поток мог использовать СОМ, он должен сначала войти в апартамент. Когда поток входит в апартамент, СОМ размещает информацию об апартаменте в локальной записи потока ( TLS – thread local storage ), и эта информация связана с потоком до тех пор, пока поток не покинет апартамент. СОМ обеспечивает доступ к объектам только для тех потоков, которые выполняются в апартаменте данного объекта. Это означает, что если поток выполняется в том же процессе, что и объект, то потоку может быть запрещено обращаться к объекту, даже если память, которую занимает объект, полностью видима и доступна. В СОМ определен HRESULT ( RPC_E_WRONG_THREAD ), который возвращают некоторые системные объекты при прямом обращении из других апартаментов. Объекты, определенные пользователем, также могут возвращать этот HRESULT ; однако лишь немногие разработчики желают пройти столь долгий путь для обеспечения правильного использования своих объектов.
В версии СОМ под Windows NT 4.0 определяется два типа апартаментов: многопоточные апартаменты ( МТА – multithreaded apartments ) и однопоточные апартаменты ( STA – singlethreaded apartments ). В каждом процессе может быть не больше одного МТА ; однако процесс может содержать несколько STA . Как следует из этих названий, в МТА может выполняться одновременно несколько потоков, а в STA – только один поток. Точнее, только один поток может когда-либо выполняться в данном STA ; что означает не только то, что к объектам, находящимся в STA , никогда нельзя будет обратиться одновременно, но также и то, что только один определенный поток может когда-либо выполнять методы объекта. Эта привязка ( affinity ) к потоку позволяет разработчикам объекта надежно сохранять промежуточное состояние между вызовами метода в локальной памяти потока TLS ( thread local storage ), а также сохранять блокировки ( locks ), требующие поточной привязки (например, критические секции Win32 и семафоры ( mutexes )).
Подобная практика приведет к катастрофе, если применять ее в случае объектов из МТА , так как в этом случае неизвестно, какой поток будет выполнять данный вызов метода. Неудобство STA заключается в том, что он позволяет одновременно выполняться только одному вызову метода, независимо от того, сколько объектов принадлежат к данному апартаменту. В случае МТА потоки могут быть распределены динамически на основании текущих запросов, вне зависимости от количества объектов в апартаменте. Для того чтобы создать параллельные серверные процессы с использованием только однопоточных апартаментов, потребуется много апартаментов, и если не соблюдать осторожность, то может возникнуть непомерное количество потоков. Кроме того, уровень параллелизма в основанных на STA обслуживающих процессах не может превышать общее число объектов в процессе. Если процесс сервера содержит только малое число крупномодульных ( coarse-grained ) объектов, то удастся обойтись малым числом потоков, даже если каждый объект существует в своем отдельном STA .
В будущей реализации СОМ будет, возможно, введен третий тип апартамента – апартамент, арендованный потоками ( RTA – rentalthreaded apartment ). Подобно МТА , RTA позволяет входить в апартамент более чем одному потоку. Но, в отличие от МТА , когда поток входит в RTA , он вызывает блокировку всего апартамента ( apartment-wide lock ) (то есть он как бы арендует апартамент), которая запрещает другим потокам одновременно входить в апартамент. Эта блокировка апартамента снимается, когда поток покидает RTA , что позволяет войти следующему потоку. В этом отношении RTA подобен МТА , за исключением того, что все вызовы методов осуществляются последовательно. Это обстоятельство делает RTA значительно удобнее для классов, относительно которых неизвестно, являются ли они потокобезопасными. Хотя все вызовы в STA также осуществляются сериями, объекты на основе RTA отличаются тем, что в них нет привязки потоков; то есть внутри RTA могут выполняться любые потоки, а не только тот исходный поток, который создал апартамент. Эта свобода от привязки к потоку делает объекты на базе RTA более гибкими и эффективными, чем объекты на основе STA , так как любой поток потенциально может сделать вызов объекта, просто войдя в RTA объекта. На момент написания этого текста еще окончательно не определились детали создания апартаментов RTA и входа в них. За подробностями вы можете обратиться к документации по SDK .
Когда поток впервые создается операционной системой как результат вызова CreateProcess или CreateThread , этому новообразованному потоку не сопоставлен ни один апартамент. Перед тем как использовать СОМ, новый поток должен войти в какой-либо апартамент путем вызова одной из приведенных далее API-функций.
В Windows NT 5.0 это будет изменено. За подробностями обращайтесь к документации по SDK.
HRESULT CoinitializeEx(void *pvReserved, DWORD dwFlags);
HRESULT Coinitialize(void *pvReserved);
HRESULT OleInitialize(vo1d *pvReserved);



Для всех трех только что описанных API-функций первый параметр зарезервирован и должен равняться нулю.
CoInitializeEx является API-функцией самого низкого уровня и позволяет вызывающему объекту определять, в какой тип апартамента нужно войти. Для того чтобы войти в МТА всего процесса, вызывающий объект должен использовать флаг
COINIT_MULTITHREADED:
HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);



Для входа во вновь соаданный STA вызывающий объект должен выставить флаг
COINIT_APARTMENTTHREADED :
HRESULT hr = CoInitializeEx(0, COINIT_APARTMENTTHREADED);



Каждый поток в процессе, который вызывает CoInitializeEx с применением COINIT_MULTITHREADED , выполняется в том же самом апартаменте. Каждый поток, который вызывает CoInitiаlizeEx с применением COINIT_APARTMENTTHREADED , выполняется в отдельном апартаменте, в который не могут входить никакие другие потоки. CoInitialize – это традиционная подпрограмма, которая просто вызывает CoInitializeEx с флагом COINIT_APARTMENTTHREADED . Olelnitialize сначала вызывает CoInitialize , а затем инициализирует несколько подсистем из OLE-приложений, таких как OLE Drag and Drop и OLE Clipboard . Если не предполагается использовать эти службы более высокого уровня, то в общем случае предпочтительнее использовать CoInitialize или CoInitializeEx .
Каждая из этих трех API-функций может быть вызвана больше одного раза на поток. Первый вызов каждого потока возвратит S_ОК . Последующие вызовы просто повторно войдут в тот же апартамент и возвратят S_FALSE . На каждый успешный вызов CoInitialize или CoInitializeEx из того же потока нужно вызвать CoUninitialize . На каждый успешный вызов OleInitialize из того же потока нужно вызвать OleUninitialize . Эти подпрограммы деинициализации ( uninitialization ) имеют очень простые сигнатуры:
void CoUninitialize(void);
void OleUninitialize(void);



Если все эти подпрограммы перед прекращением потока или процесса не вызваны, это может задержать восстановление ресурсов. Когда поток входит в апартамент, недопустимо изменять типы апартамента с использованием CoInitiаlizeEx . При попытках сделать это HRESULT будет содержать RPC_E_CHANGED_MODE . Однако, если поток полностью покинул апартамент посредством CoUninitialize , он может войти в другой апартамент путем повторного вызова CoInitializeEx .
Опубликовал Kest July 13 2009 14:36:15 · 0 Комментариев · 6215 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
C++ : библиотека ...
mp3tag
Шейдеры в Delphi
Image Browser [Ис...
MpegPlay
Фильтры изображений
32 урока по Delphi
Report
Visual Basic Script
Факториал [Исходн...
Генетический алго...
Программирование ...
Pro-Download Sys...
Игра в крестики н...
Задача о 8ми ладьях
XPmenu
MPTools
Atb
Правила программи...
FatScrollbar

Топ загрузок
Приложение Клие... 100481
Delphi 7 Enterp... 87905
Converter AMR<-... 20082
GPSS World Stud... 13571
Borland C++Buil... 12072
Borland Delphi ... 8676
Turbo Pascal fo... 7048
Visual Studio 2... 5005
Калькулятор [Ис... 4912
FreeSMS v1.3.1 3545
Случайные статьи
Оператор выбора case
Несложное комбинир...
Aura SE Parser / Л...
Грубые оценки
Область Range
ИСПОЛЬЗОВАНИЕ ОТСЕ...
Вычисление произво...
Общее представление
Файл HelloAndroidA...
• Модернизированны...
Форма, демонстри...
Создание потоков с...
Метаданные
Песочные часы
Методики авторизац...
Проблемы с USB под...
Поиск потерявшихся...
Плохая функция: ве...
Простейший протокол
Комплект разработч...
Элементы управлени...
Блоки работы со сп...
Чтение текста из д...
Трояны - это свои ...
Многократная рекурсия
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?