и все бы хорошо, если бы у структуры SData был
конструктор копирования, например такой:
SData(const
SData data)
{
CScopeLock lock(data.m_lock);
m_dwSmth = data.m_dwSmth;
}
|
Но нет, программист посчитал, что хватит за глаза
простого копирования полей, и, в результате, переменная m_lock была просто
скопирована, хотя именно в этот момент из другой нити она была
"захвачена", и значение поля LockCount у нее в этот момент больше
либо равно нулю. После вызова ::LeaveCriticalSection() в той нити, у исходной
переменной m_lock значение поля LockCount уменьшилось на единицу. А у
скопированной переменной – осталось прежним. И любой вызов ::EnterCriticalSection()
в этой нити никогда не вернется. Он будет вечно ждать неизвестно чего.
Это только цветочки. С ягодками вы очень быстро
столкнетесь, если попытаетесь написать что-нибудь действительно сложное.
Например, ActiveX-объект в многопоточном подразделении (MTA), создаваемый из
скрипта, запущенного из-под контейнера, размещенного в однопоточном
подразделении (STA). Ни слова не понятно? Не беда. Сейчас я попытаюсь выразить
проблему более понятным языком. Итак. Имеется объект, вызывающий методы другого
объекта, причем живут они в разных нитях. Вызовы производятся синхронно. Т.е.
объект №1 переключает выполнение на нить объекта №2, вызывает метод и
переключается обратно на свою нить. При этом выполнение нити №1 приостановлено
до тех пор, пока не отработает нить объекта №2. Теперь, положим, объект №2
вызывает метод объекта №1 из своей нити. Получается, что управление вернулось в
объект №1, но из нити объекта №2. Если объект №1 вызывал метод объекта №2, захватив какую-либо критическую секцию, то при вызове метода объекта №1 тот
заблокирует сам себя при повторном входе в ту же критическую секцию.
Листинг 11. Самоблокировка средствами одного объекта.
// Нить №1
void IObject1::Proc1()
{
// Входим в критическую секцию объекта №1
m_lockObject.Lock();
// Вызываем метод объекта №2, происходит
переключение на нить объекта №2
m_pObject2->SomeMethod();
// Сюда мы попадем только по возвращении из
m_pObject2->SomeMethod()
m_lockObject.Unlock();
}
// Нить №2
void IObject2::SomeMethod()
{ Рекомендуем скачать другие рефераты по теме: реферат на экономическую тему, инновационная деятельность.
Предыдущая страница реферата | 7
8
9
10
11
12
13
14
15
16
17 | Следующая страница реферата
|
|