Алекс Jenter - Программирование на Visual C++. Архив рассылки

Здесь есть возможность читать онлайн «Алекс Jenter - Программирование на Visual C++. Архив рассылки» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Программирование на Visual C++. Архив рассылки: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Программирование на Visual C++. Архив рассылки»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ
, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.

Программирование на Visual C++. Архив рассылки — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Программирование на Visual C++. Архив рассылки», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

// стека для __LINE__ и __FILE__ сделает нашу систему

// более громоздкой. Если это действительно необходимо,

// Вы всегда можете сделать это самостоятельно

pcs->RecursionCount++;

return;

}

// Критическая секция занята другой нитью.

// Придется подождать

_WaitForCriticalSectionDbg(pcs, nLine, azFile);

}

// Либо критическая секция была "свободна",

// либо мы дождались. Сохраняем идентификатор текущей нити.

pcs->OwningThread = (HANDLE)::GetCurrentThreadId();

pcs->RecursionCount = 1;

pcs->m_nLine = nLine;

pcs->m_azFile = azFile;

}

// Заполучаем критическую секцию если она никем не занята

inline BOOL TryEnterCriticalSectionDbg(LPCRITICAL_SECTION_DBG pcs, int nLine, LPSTR azFile) {

if (-1L == ::InterlockedCompareExchange(&pcs->LockCount, 0, -1)) {

// Это первое обращение к критической секции

pcs->OwningThread = (HANDLE)::GetCurrentThreadId();

pcs->RecursionCount = 1;

pcs->m_nLine = nLine;

pcs->m_azFile = azFile;

} else if (pcs->OwningThread == (HANDLE)::GetCurrentThreadId()) {

// Это не первое обращение, но из той же нити

::InterlockedIncrement(&pcs->LockCount);

pcs->RecursionCount++;

} else return FALSE; // Критическая секция занята другой нитью

return TRUE;

}

// Освобождаем критическую секцию

inline VOID LeaveCriticalSectionDbg(LPCRITICAL_SECTION_DBG pcs) {

// Проверяем, чтобы идентификатор текущей нити совпадал

// с идентификатором нити-влядельца.

// Если это не так, скорее всего мы имеем дело с ошибкой

ATLASSERT(pcs->OwningThread == (HANDLE)::GetCurrentThreadId());

if (--pcs->RecursionCount) {

// Не последний вызов из этой нити.

// Уменьшаем значение поля LockCount

::InterlockedDecrement(&pcs->LockCount);

} else {

// Последний вызов. Нужно "разбудить" какую-либо

// из ожидающих ниток, если таковые имеются

ATLASSERT(NULL != pcs->OwningThread);

pcs->OwningThread = NULL;

pcs->m_nLine = 0;

pcs->m_azFile = NULL;

if (::InterlockedDecrement(&pcs->LockCount) >= 0) {

// Имеется, как минимум, одна ожидающая нить

_UnWaitCriticalSectionDbg(pcs);

}

}

}

// Удостоверяемся, что ::EnterCriticalSection() была вызвана

// до вызова этого метода

inline BOOL CheckCriticalSection(LPCRITICAL_SECTION pcs) {

return pcs->LockCount >= 0

&& pcs->OwningThread == (HANDLE)::GetCurrentThreadId();

}

// Переопределяем все функции для работы с критическими секциями.

// Определение класса CLock должно быть после этих строк

#define InitializeCriticalSection InitializeCriticalSectionDbg

#define InitializeCriticalSectionAndSpinCount(pcs, c) \

InitializeCriticalSectionDbg(pcs)

#define DeleteCriticalSection DeleteCriticalSectionDbg

#define EnterCriticalSection(pcs) EnterCriticalSectionDbg(pcs, __LINE__, __FILE__)

#define TryEnterCriticalSection(pcs) TryEnterCriticalSectionDbg(pcs, __LINE__, __FILE__)

#define LeaveCriticalSection LeaveCriticalSectionDbg

#define CRITICAL_SECTION CRITICAL_SECTION_DBG

#define LPCRITICAL_SECTION LPCRITICAL_SECTION_DBG

#define PCRITICAL_SECTION PCRITICAL_SECTION_DBG

#endif

Приводим наши классы в соответствие

Листинг 17. Классы CLock и CScopeLock, вариант для отладки

class CLock {

friend class CScopeLock;

CRITICAL_SECTION m_CS;

public:

void Init() { ::InitializeCriticalSection(&m_CS); }

void Term() { ::DeleteCriticalSection(&m_CS); }

#if defined(CS_DEBUG)

BOOL Check() { return CheckCriticalSection(&m_CS); }

#endif

#if CS_DEBUG > 1

void Lock(int nLine, LPSTR azFile) {

EnterCriticalSectionDbg(&m_CS, nLine, azFile);

}

BOOL TryLock(int nLine, LPSTR azFile) {

return TryEnterCriticalSectionDbg(&m_CS, nLine, azFile);

}

#else

void Lock() {

::EnterCriticalSection(&m_CS);

}

BOOL TryLock() {

return ::TryEnterCriticalSection(&m_CS);

}

#endif

void Unlock() {

::LeaveCriticalSection(&m_CS);

}

};

class CScopeLock {

LPCRITICAL_SECTION m_pCS;

public:

#if CS_DEBUG > 1

CScopeLock(LPCRITICAL_SECTION pCS, int nLine, LPSTR azFile) : m_pCS(pCS) {

Lock(nLine, azFile);

}

CScopeLock(CLock& lock, int nLine, LPSTR azFile) : m_pCS(&lock.m_CS) {

Lock(nLine, azFile);

}

void Lock(int nLine, LPSTR azFile) {

EnterCriticalSectionDbg(m_pCS, nLine, azFile);

}

#else

CScopeLock(LPCRITICAL_SECTION pCS) : m_pCS(pCS) { Lock(); }

CScopeLock(CLock& lock) : m_pCS(&lock.m_CS) { Lock(); }

void Lock() { ::EnterCriticalSection(m_pCS); }

#endif

~CScopeLock() { Unlock(); }

void Unlock() { ::LeaveCriticalSection(m_pCS); }

};

#if CS_DEBUG > 1

#define Lock() Lock(__LINE__, __FILE__)

#define TryLock() TryLock(__LINE__, __FILE__)

#define lock(cs) lock(cs, __LINE__, __FILE__)

#endif

К сожалению, пришлось даже переопределить CScopeLock lock(cs), причем мы жестко привязались к имени переменной. Не говоря уж о том, что у нас наверняка получился конфликт имен, все-таки Lockдовольно популярное название для метода. Такой код не будет собираться, например, с популярнейшей библиотекой ATL. Тут есть два способа. Переименовать наши методы Lock() и TryLock() во что-нибудь более уникальное либо переименовать Lock() в ATL:

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Программирование на Visual C++. Архив рассылки»

Представляем Вашему вниманию похожие книги на «Программирование на Visual C++. Архив рассылки» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Алексей Макеев - Смертельный архив
Алексей Макеев
libcat.ru: книга без обложки
Алексей Апухтин
Отзывы о книге «Программирование на Visual C++. Архив рассылки»

Обсуждение, отзывы о книге «Программирование на Visual C++. Архив рассылки» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x