Использование объектов критически важных разделов

В следующем примере показано, как поток инициализирует, вводит и освобождает критически важный раздел. Он использует функции InitializeCriticalSectionAndSpinCount, EnterCriticalSection, LeaveCriticalSectionи DeleteCriticalSection.

Warning

Риск взаимоблокировки: Если поток должен получать несколько критически важных разделов, всегда получать их в согласованном, документированного порядка во всех потоках. Получение блокировок в разных заказах из разных потоков является наиболее распространенной причиной взаимоблокировок. Кроме того, обратите внимание, что EnterCriticalSection блокирует выполнение на неопределённое время — используйте TryEnterCriticalSection для неблокирующих попыток захвата и реализуйте ограниченный цикл повторных попыток с тайм-аутом, если требуется захват блокировки с тайм-аутом.

Note

Современная альтернатива C++: Для нового кода рекомендуется использовать std::mutex или std::lock_guardstd::scoped_lock (C++17), которые обеспечивают управление блокировкой на основе RAII, которое обеспечивает выпуск даже при возникновении исключений. Для нагрузок с преобладанием операций чтения рассмотрите тонкие блокировки чтения/записи (SRW) или std::shared_mutex.

// Global variable
CRITICAL_SECTION CriticalSection; 

int main( void )
{
    ...

    // Initialize the critical section one time only.
    if (!InitializeCriticalSectionAndSpinCount(&CriticalSection, 
        0x00000400) ) 
        return;
    ...

    // Release resources used by the critical section object.
    DeleteCriticalSection(&CriticalSection);
}

DWORD WINAPI ThreadProc( LPVOID lpParameter )
{
    ...

    // Request ownership of the critical section.
    EnterCriticalSection(&CriticalSection); 

    // Access the shared resource.

    // Release ownership of the critical section.
    LeaveCriticalSection(&CriticalSection);

    ...
return 1;
}