Реферат: Критические секции
#endif
Ну и заодно добавим еще один метод в наш класс Clock (листинг 15).
Листинг 15. Класс CLock с новым методом.
class CLock { friend class CScopeLock; CRITICAL_SECTION m_CS; public: void Init() { ::InitializeCriticalSection(&m_CS); } void Term() { ::DeleteCriticalSection(&m_CS); } void Lock() { ::EnterCriticalSection(&m_CS); } BOOL TryLock() { return ::TryEnterCriticalSection(&m_CS); } void Unlock() { ::LeaveCriticalSection(&m_CS); } BOOL Check() { return CheckCriticalSection(&m_CS); } }; |
Использовать метод Check() в release-конфигурациях не стоит, возможно, что в будущем, в какой-нибудь Windows64, структура RTL_CRITICAL_SECTION изменится, и результат такой проверки будет не определен. Так что ему самое место "жить" внутри всяческих ASSERT'ов.
Итак, что мы имеем? Мы имеем проверку на лишний вызов ::LeaveCriticalSection() и ту же трассировку для блокировок. Не так уж много. Особенно если трассировка о блокировке имеет место, а вот нить, забывшая освободить критическую секцию, давно завершилась. Как быть? Вернее, что бы еще придумать, чтобы ошибку проще было выявить? Как минимум, прикрутить сюда __LINE__ и __FILE__, константы, соответствующие текущей строке и имени файла на момент компиляции этого метода.
VOID EnterCriticalSectionDbg(LPCRITICAL_SECTION pcs , int nLine = __LINE__, azFile = __FILE__); |
Компилируем, запускаем... Результат удивительный. Хотя правильный. Компилятор честно подставил номер строки и имя файла, соответствующие началу нашей EnterCriticalSectionDbg(). Так что придется попотеть немного больше. __LINE__ и __FILE__ нужно вставить в #define'ы, тогда мы получим действительные номер строки и имя исходного файла. Теперь вопрос, куда же сохранить эти параметры для дальнейшего использования? Причем хочется оставить за собой возможность вызова стандартных функций API наряду с нашими собственными? На помощь приходит C++: просто создадим свою структуру, унаследовав ее от RTL_CRITICAL_SECTION (листинг 16).
Листинг 16. Реализация критических секций с сохранением строки и имени файла.
#if defined(_DEBUG) && !defined(_NO_DEADLOCK_TRACE) #define DEADLOCK_TIMEOUT 30000 #define CS_DEBUG 2 // Нашаструктуравзамен CRITICAL_SECTION struct CRITICAL_SECTION_DBG : public CRITICAL_SECTION { // Добавочные поля int m_nLine; К-во Просмотров: 773
Бесплатно скачать Реферат: Критические секции
|