Systems/Windows2010.07.13 11:12
일반적인 Unix 플랫폼에서는 멀티 쓰레드 응용 프로그램을 작성하기 위해 pthread 라이브러리를 활용한다. pthread 라이브러리는 자체적으로 conditional variable을 지원하기 때문에, 그것을 활용해서 쓰레드간 동기화를 편하게 할 수 있다. 

그런데 WIN32 플랫폼에 이르면, Vista 전까지는 conditional variable을 지원하지 않았다. 따라서 conditional variable을 사용하기 위해 직접 conditional variable 기능을 구현하는 삽질을 해야만 했다.

하지만 vista 부터는 (Windows 7도 당근) conditional variable을 지원한다. 다음과 같이 사용하면 된다.

우선, pthread와 마찬가지로 conditional variable을 통한 동기화를 하려면 critial section과 같이 써야 한다. (pthread 라이브러리에서는 mutex와 같이 써야 했다.)

CRITICAL_SECTION critical_section;
CONDITION_VARIABLE conditional_variable;

초기화는 다음과 같이 한다.

// 이하는 전부
// pthread_mutexattr_init
// pthread_mutex_init
// pthread_condattr_init
// pthread_cond_iint에 대응한다.
InitializeConditionVariable(&conditional_variable);
InitializeCriticalSection(&critical_section);

다 쓰고 나면 삭제해 줘야 한다.

// 이하는 전부
// pthread_condattr_destroy
// pthread_cond_destroy
// pthread_mutexattr_destroy
// pthread_mutex_destroy에 대응한다.
DeleteCriticalSection(&critical_section);

conditional variable에 대한 락, 그러니까 동기화 지점에 대한 락은 critical section을 통해 해야 한다.

// pthread_mutex_lock에 대응
EnterCriticalSection(&critical_section);

락 해제는 다음과 같이 한다.

// pthread_mutex_unlock에 대응
LeaveCriticalSection(&critical_section);

특정한 조건이 만족되었는지 무한 대기하려면 다음과 같이 한다. (오류 체크 코드는 싹 다 뺐다.)

// pthread_cond_wait에 대응
SleepConditionVariableCS(&conditional_variable, &critical_section, INFINITE);

일정한 시간 동안만 대기하려면 다음과 같이 하면 된다. (초 단위로 대기하려는 경우)

// pthread_cond_timedwait에 대응
SleepConditionVariableCS(&conditional_variable, &critical_section, second * 1000);

조건이 충족되었을 경우 conditional variable 상에서 기다리고 있는 쓰레드들을 깨우는 방법으로는 다음의 두 가지가 있다.

// pthread_cond_signal에 대응
WakeConditionVariable(&conditional_variable);
// pthread_cond_broadcast에 대응
WakeAllConditionVariable(&conditional_variable);

위의 WIN32 프리미티브들을 활용하면 WIN32 쓰레드를 conditional variable을 활용하여 동기화할 수 있다. (Windows에서는 condition variable 이라고 부른다.)
신고
Posted by 이병준

소중한 의견, 감사합니다. ^^