What are critical sections in Win32?

Posted: (EET/GMT+2)

 

When writing multithreaded Windows applications, you sometimes need to make sure that two threads don't access the same data at the same time. If several threads modify the same variable or data structure, the results can be quite unexpected.

For example, imagine that two threads are updating a counter. Both threads might read the current value before either one has written the new value. In this situation, one of the updates can be lost.

The Win32 API provides a synchronization mechanism called a critical section. It allows only one thread at a time to execute a protected part of the program.

To use a critical section, first declare and initialize a CRITICAL_SECTION structure:

CRITICAL_SECTION cs;

InitializeCriticalSection(&cs);

Before accessing shared data, a thread calls EnterCriticalSection(). If another thread is already inside the critical section, the calling thread must wait until it becomes available.

EnterCriticalSection(&cs);

/* access shared data */
counter++;

LeaveCriticalSection(&cs);

The LeaveCriticalSection() function releases the critical section, allowing another waiting thread to continue. When the critical section is no longer needed, its resources should be released:

DeleteCriticalSection(&cs);

All threads accessing the shared variable must use the same critical section. Otherwise, the protection will not work correctly.

One important detail is that critical sections can only synchronize threads within the same process. If you need synchronization between different processes, Windows also provides mutex objects.

Critical sections are generally quite efficient, but you should keep the protected code as short as possible. A thread waiting for a critical section cannot continue until the owning thread leaves it.

Also remember that every successful EnterCriticalSection() call must have a corresponding LeaveCriticalSection() call. Forgetting to release a critical section can cause other threads to wait indefinitely.