Реферат: Критические секции
// Нить №2
void IObject1::Proc2()
{
// Пытаемся войти в критическую секцию объекта №1
m_lockObject.Lock();
// Сюда мы не попадем никогда
m_lockObject.Unlock();
}
Если бы в примере не было переключения нитей, все вызовы произошли бы в нити объекта №1, и никаких проблем не возникло. Сильно надуманный пример? Ничуть. Именно переключение ниток лежит в основе подразделений (apartments) COM. А из этого следует одно очень, очень неприятное правило.
СОВЕТ Избегайте вызовов каких бы то ни было объектов при захваченных критических секциях. |
Помните пример из начала статьи? Так вот, он абсолютно неприемлем в подобных случаях. Его придется переделать на что-то вроде примера, приведенного в листинге 12.
Листинг 12. Простой пример, не подверженный самоблокировке.
// Нить №1 void Proc1() { m_lockObject.Lock(); CComPtr<IObject> pObject(m_pObject); // вызов pObject->AddRef(); m_lockObject.Unlock(); if (pObject) pObject->SomeMethod(); } // Нить №2 void Proc2(IObject *pNewObject) { m_lockObject.Lock(); m_pObject = pNewobject; m_lockObject.Unlock(); } |