ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C++ Synchronization Object (동기화 객체, CriticalSection, Mutex, Semaphore, Event)
    Search: 카테고리 없음 카테고리 없음 2016. 1. 25. 16:58

    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


    댓글