Критические секции
Критические секции являются наиболее простым средством синхронизации задач для обеспечения последовательного доступа к ресурсам. Они работают быстро, не снижая заметно производительность системы, но обладают одним существенным недостатком - их можно использовать только для синхронизации задач в рамках одного процесса. В отличие от критических секций объекты Mutex, которые мы рассмотрим немного позже, допускают синхронизацию задач, созданных разными процессами.
Критическая секция создается как структура типа CRITICAL_SECTION:
CRITICAL_SECTION csWindowPaint;
Обычно эта структура располагается в области глобальных переменных, доступной всем запущенным задачам процесса. Так как каждый процесс работает в своем собственном адресном пространстве, вы не сможете передать адрес критической секции из одного процесса в другой. Именно поэтому критические секции нельзя использовать для синхронизации задач, созданных разными процессами.
В файле winbase.h (который включается автоматически при включении файла windows.h) структура CRITICAL_SECTION и указатели на нее определены следующим образом:
typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION;
typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION;
Определение недокументированной структуры RTL_CRITICAL_SECTION вы можете найти в файле winnt.h:
typedef struct _RTL_CRITICAL_SECTION
{
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
LONG LockCount; // счетчик блокировок
LONG RecursionCount; // счетчик рекурсий
HANDLE OwningThread; // идентификатор задачи, владеющей
// секцией
HANDLE LockSemaphore; // идентификатор семафора
DWORD Reserved; // зарезервировано
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
Заметим, однако, что нет никакой необходимости изменять поля этой структуры вручную, так как для этого есть специальные функции. Более того, только эти функции и можно использовать для работы с критическими секциями. В документации SDK также отмечено, что структуру типа CRITICAL_SECTION нельзя перемещать или копировать.