Windows API
본 시리즈에서는 Windows API 개별 함수에 대해 간략한 사용법 및 응용에 대해 정리한다.
이전 게시글: 스레드의 생존 여부 확인하기
다음 게시글: OutputDebugString을 printf처럼 서식(포맷) 적용하여 사용하기
크리티컬 섹션을 사용하여 스레드간 변수 공유
본 포스팅에서는 크리티컬 섹션(CRITICAL_SECTION
) 구조체를 사용하여 스레드간 변수를 공유하는 방법에 대해 정리한다.
CRITICAL_SECTION
스레드간 공유하고자 하는 변수와 함께 CRITICAL_SECTION
구조체 변수를 선언한다.
/* 스레드간 공유하고자 하는 정수형 변수 */
DWORD g_dwInteger = 0;
/* 상기 정수형 변수에 접근하려면 아래 구조체를 통해 권한을 얻어야 한다. */
CRITICAL_SECTION g_stCriticalSection;
InitializeCriticalSection
CRITICAL_SECTION
구조체를 사용하기 위해서는 반드시 리셋되어야 한다. 구조체를 리셋하는 함수는 InitializeCriticalSection
이다.
VOID InitializeCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
lpCriticalSection
매개변수를 통해 리셋할 CRITICAL_SECTION
을 지정한다.
InitializeCriticalSection(&g_stCriticalSection);
EnterCriticalSection, LeaveCriticalSection
VOID EnterCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
BOOL TryEnterCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
VOID LeaveCriticalSection(
LPCRITICAL_SECTION lpCriticalSection
);
스레드간 공유 변수에 접근할 때 EnterCriticalSection
으로 크리티컬 섹션에 진입하고 공유 변수 사용이 끝나면 LeaveCriticalSection
으로 크리티컬 섹션을 벗어난다. EnterCriticalSection
은 타 스레드에서 크리티컬 섹션을 사용하고 있을 때 대기한다. 대기과정(현재 스레드의 중지) 없이 즉시 사용중 여부를 확인하고자 하면 TryEnterCriticalSection
을 사용한다. 임계영역에 진입했다면 TRUE
를 반환하고 그렇지 못했다면 FALSE
를 반환한다.
EnterCriticalSection(&g_stCriticalSection);
{
/* ... g_dwInteger에 대한 읽고 쓰기 */
}
LeaveCriticalSection(&g_stCriticalSection);
실행 예제
다음은 크리티컬 섹션의 실행 예이다. 창에 대한 스레드, 콘솔창에 대한 스레드 총 2개의 스레드가 실행중이며 콘솔창으로 1부터 30까지 센 후 콘솔창은 닫힌다. 창의 버튼을 클릭하면 콘솔창에서 세고 있는 숫자는 1로 리셋된다. 이 과정에서 크리티컬 섹션이 사용된다.