-
C++ 동기화 객체 (CriticalSection, Mutex, Semaphore, Event)
1. Critical Section
- 특징: 유일하게 커널 객체를 사용하지 않아 빠름. 동일한 프로셋 내에서만 사용.
- 사용
void InitializeCriticalSection(LPCRITICAL_SECTION lpCs);
void DeleteCriticalSection(LPCRITICAL_SECTION lpCs);
void work()
{
EnterCriticalSection(lpCs); //lock.
//TODO : use
LeavCriticalSection(lpCs); //unlock.
}
2. Mutex (Mutual((둘 이상 사람들) 공동의) Exclusion(제외 배제 차단))
- 특징: 대상에 하나의 경로 동기화. 자신이 소유한 쓰레드 기억, 쓰레드 종료될 경우 강제로 Signaled 상태(WaitForSingleobject() 리턴값 WAIT_ABANDONED)를 만듬(Cs와 다른점).
- 사용
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, //보안 속성으로 보통 NULL로 지정.
BOOL bInitialOwner, //true시 쓰레드가 바로 뮤텍스를 소유하면서 다른 쓰레드는 소유할 수 없게 됨.
LPCTSTR lpName); //뮤텍스의 이름으로 NULL 설정 가능, 전역적으로 유일한 값.
// Return 값은 뮤텍스의 핸들이다.
HANDLE OpenMutex(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName);
BOOL ReleaseMutex(HANDLE hMutex); //소유 해제하여 다른 쓰레드게 가질수 있게 함.
HRESULT CloseHandle(HANDLE hHandle); //리턴 값 S_OK시 생성된 뮤텍스를 파괴성공, 그외엔 에러.
3. Semaphore
- 특징: 대상에 일정 개수의 경로 동기화.
- 사용:
#include <process.h>
HANDLE CreateSemaphore( //리턴값 세마포어 핸들 반환, NULL이면 오류.
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG iInitialCount, //초기값을 지정.
LONG iMaximumCount, //최대 사용 개수.
LPCTSTR lpName);
BOOL ReleaseSemaphore(
HANDLE hSemaphore,
LONG iReleaseCount, //반환 자원의 개수. 남은 수 보다 많을시 오류와 함께 무효.
LPLONG lpPreviousCount); //세마포어 이전 카운트를 리턴받기 위한 참조 인수. NULL 가능.
HANDLE OpenSemaphore(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSRT lpName);
HRESULT CloseHandle(HANDLE hHandle); //리턴 값 S_OK시 생성된 세마포어를 파괴성공, 그외엔 에러.
{//main thread
s1 = CreateSemaphore(NULL, 0, 2, NULL);
ReleaseSemaphore(s1, 1, NULL);
WaitForMultipleObjects(1, WorkThread1, TRUE, INFINITE); //지정 개수만큼 Thread 대기, 리턴 0=성공 -1=실패.
}
{//WorkThread1
WaitForSingleObject(s1, INFINITE);
//work
ReleaseSemaphore(s1, 1, NULL);
}
4. Event
- 특징: 쓰레드의 작업 순서나 시기를 조정하기 위해 사용.
- 사용:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset, //이벤트를 수동 리셋(대기 상태가 종료되면 자동으로 Non-Signaled로 만들어 주지 않는)으로 설정.
BOOL bInitialState, //TRUE이면 자동으로 Signaled 상태로 들어가 이벤트를 기다리는 쓰레드가 곧바로 실행가능.
LPCTSTR lpName);
HANDLE OpenEvent(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSRT lpName);
BOOL SetEvent(HANDLE hEvent); //임의로 Signaled 상태와 Non-Signaled 상태를 설정가능.
BOOL ResetEvent(HANDLE hEvent); //Non-Signaled 상태로 만듬. 여러 개의 쓰레드를 위해서 이벤트를 사용문제 가능. 그러므로 수동 리셋으로 이벤트를 생성 후 ResetEvent 함수로 수동리셋 하도록.
5. Mutex (pthread.h사용)
#include<pthread.h>
void *Workthread1(void * arg);
{//main thread
//뮤텍스를 초기화.
state = pthread_mutex_init(&mutx,NULL);
if(state) puts("Error mutex initialization");
//2개의 쓰레드를 생성.
pthread_create(&t1,NULL,Workthread1,&thread1);
pthread_create(&t2,NULL,Workthread1,&thread2);
//쓰레드 종료 대기
pthread_join(t1,&thread_result);
pthread_join(t2,&thread_result);
pthread_mutex_destroy(&mutx); //뮤텍스 종료함수.
}
void *Workthread1(void *arg)
{
pthread_mutex_lock(&mutx);
sleep(1000); // work
pthread_mutex_unlock(&mutx);
}
참고: http://topnanis.tistory.com/195
6. Semaphore (pthread.h사용)
#include<pthread.h>
sem_t s1;
void *ThreadSend(void * arg);
void *ThreadRecv(void * arg);
{//main thread
state = sem_init(&s1,0,0); //초기화, 0으로 시작.
if(state != 0) puts("Error");
//쓰레드를 생성합니다.
pthread_create(&t1,NULL,ThreadSend,&thread1);
pthread_create(&t2,NULL,ThreadRecv,&thread2);
pthread_create(&t3,NULL,ThreadRecv,&thread3);
//쓰레드 종료 대기
pthread_join(t1,&thread_result);
pthread_join(t2,&thread_result);
pthread_join(t3,&thread_result);
sem_destroy(&bin_sem); //세마포어 소멸
}
void *ThreadSend(void *arg)
{
sleep(1000); //work
sem_post(&s1); //s1=1
}
void *ThreadRecv(void *arg)
{
sem_wait(&s1); //s1=0
sleep(1000); // work
}
참고: http://topnanis.tistory.com/195