Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Создание инверсных семафоров и типов данных, безопасных в многопоточной среде - часть 2


Первый класс, CResGuard, охраняет доступ к ресурсу. Он содержит два элемента данных: CRITICAL_SECTION и LONG. Последний используется для слежения за тем, сколько раз поток, владеющий ресурсом, входил в критическую секцию. Эта инфор мация полезна при отладке. Конструктор и деструктор объекта CResGuard вызывают сответственно InitializeCriticalSeclion и DeleteCriticalSection. Поскольку создать объект может лишь единственный поток, конструктор и деструктор какого-либо С++-объек та не обязательно должен быть реентерабельным. Функция-член IsGuarded просто сообщает, была ли хоть раз вызвана EnterCriticalSection для данного объекта. Как я уже говорил, все это предназначено для отладки. Включение CRITICAL_SECTION в C++ объект гарантирует корректность инициализации и удаления критической секции.

Класс CResGuard также включает открытый вложенный С++-класс CGuard. Объект CGuard содержит ссылку на объект CResGuard и предусматривает лишь конструктор и деструктор. Конструктор обращается к функции-члену Guard класса CResGuard, вызывающей EnterCriticalSection, а деструктор — к функции-члену Unguard того же класса, вызывающей LeaveCriticalSection. Такая схема упрощает манипуляции с CRITI CAL_SECTION. Вот небольшой фрагмент кода, иллюстрирующий применение этих классов:

struct SomeDataStruct
{
...
} g_SomeSharedData;

// Создаем объект CResGuard, защищающий g_SomeSharedData.
// Примечание: Конструктор инициализирует критическую секцию, а деструктор удаляет ее.

CResGuard g_rgSomeSharedData;

void AFunction()
{

// эта функция работает с разделяемой структурой данных

// защищаем ресурс от одновременного доступа со стороны нескольких потоков
CResGuard::CGuard gDummy(g_rgSomeSharedData);
// входим в критическую секцию

// работаем c ресурсом g_SomeSharedData

...

}
// Примечание: LeaveCriticalSection вызывается, когда gDummy
// выходит за пределы области видимости

Следующий С++-класс, CInterlockedType, содержит все, что нужно для создания объекта данных, безопасного в многопоточной среде. Я сделал CInterlockediype клас сом шаблона, чтобы его можно было применять для любых типов данных. Поэтому Вы можете использовать его, например, с целочисленной переменной, строкой или произвольной структурой данных.




Начало  Назад  Вперед