сожалению, пришлось даже переопределить CScopeLock lock(cs), причем мы жестко привязались к имени переменной. Не говоря уж о том, что у нас наверняка получился
конфликт имен, все-таки Lock довольно популярное название для метода. Такой код не будет собираться, например, с популярнейшей библиотекой ATL. Тут есть два способа. Переименовать наши методы Lock и TryLock во что-нибудь более уникальное либо переименовать Lock в ATL:
// StdAfx.h
// …
#define Lock ATLLock
#include <AtlBase.h>
// …
Сменим тему
А что это мы все про Win32 API да про C++? Давайте посмотрим, как обстоят дела с критическими секциями в более современных языках программирования.
C#
Тут мы стараниями Майкрософт имеем полный набор старого доброго API под новыми именами.
Критические секции представлены классом System.Threading.Monitor, вместо ::EnterCriticalSection есть Monitor.Enter(object), а вместо ::LeaveCriticalSection Monitor.Exit(object), где object – это любой объект C#. Т.е. каждый объект где-то в потрохах CLR (Common Language Runtime) имеет свою собственную критическую секцию. Либо заводит ее по необходимости. Типичное использование этой секции выглядит так:
Monitor.Enter(this);
m_dwSmth = dwSmth;
Monitor.Exit(this);
Если нужно организовать отдельную критическую секцию для какой-либо переменной самым логичным способом будет поместить ее в отдельный объект и использовать этот объект как аргумент при вызове Monitor.Enter/Exit. Кроме того, в C# существует ключевое слово lock, это полный аналог нашего класса CScopeLock.
lock(this) {
m_dwSmth = dwSmth;
}
А вот Monitor.TryEnter в C# (о, чюдо!) принимает в качестве параметра максимальный период ожидания.
Замечу, что CLR это не только C#, все это применимо и к другим языкам, использующим CLR.
Java
В этом языке используется подобный механизм, только место ключевого слова lock есть ключевое слово synchronized, а все остальное будет точно так же.
synchronized(this) {
m_dwSmth = dwSmth;
}
MC++ (управляемый C++)
Тут тоже появился атрибут [synchronized] ведущий себя точно также, как и одноименное ключевое слово из Java. Странно, что архитекторы из Майкрософт решили позаимствовать синтаксис из продукта от Sun Microsystems вместо своего собственного.
[synchronized] DWORD m_dwSmth;
//...
m_dwSmth = dwSmth; // неявный вызов Lock(this)
Delphi
Практически все, что верно для C++, верно и для Delphi. Критические секции представлены объектом TCriticalSection. Собственно, это такая же обертка как и наш класс CLock.
Кроме того, в Delphi присутствует специальный объект TMultiReadExclusiveWriteSynchronizer с названием, говорящим само за себя.
Подведем итоги
Итак, что нужно знать о критических секциях:
• Критические секции работают быстро и не требуют большого количества системных ресурсов.