CreateSemaphore

한정된 리소스를 각 쓰레드들에게 분배해야 하는 경우가 있다. 쓰레드 개수가 3개밖에 없는 경우 쓰레드 3개만 일단 돌리고, 나머지 7개는 대기하고 있다가, 3개중에 사용이 끝나면 7개중에 하나가 사용되는 식으로, 세마 포어는 사용되는 갯수를 조정할 수가 있다.

윈도우즈에서 사용 할 수 있는 세마포어 API를 다음의 함수로 만들었다.
재 사용을 위한 목적보다, 설명을 위한 목적으로 함수로 만들었다.

HANDLE g_hSemaphore;

void CreateSemaphore()

{

    g_hSemaphore = CreateSemaphore(NULL, 1, MAX_THREAD_NUM, NULL);

}

 

void LockSemaphore()

{

    WaitForSingleObject(g_hSemaphore, INFINITE);

}

 

void UnLockSemaphore() //리소스 카운트를

{

    ReleaseSemaphore(g_hSemaphore, 1, NULL);

}

 

void CloseSemaphore()

{

    CloseHandle(g_hSemaphore);

}

HANDLE CreateSemaphore(
  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, //보안 속성, 일반적으로 NULL 지정
  LONG lInitialCount,  //임계영역 갯수          
  LONG lMaximumCount, //임계영역 접근 갯수     
  LPCTSTR lpName      //Mutex 와 동일하게 Name 지정
)

화장실에 비유하자면 lInitialCount 화장실 갯수, lMaximumCount 화장실에 접근 할 수 있는 사람 여기서는 MAX_THREAD_NUM, 3이다.
(예제 프로그램을 실행해 보면, lInitialCount와 lMaximumCount 같은 숫자 1을 넣어도 실행에는 문제가 없다.)

WaitForSingleObject(g_hSemaphore, INFINITE);
화장실에 들어간다. 세마포어 카운트를 감소 시킨다.
lInitialCount 값에서 감소 시킨다.. 세마포어 카운트가 0이면 Lock 상태가 된다.

ReleaseSemaphore(g_hSemaphore, 1, NULL);
화장실을 나온다, 세마포어 카운트를 증가 시킨다.

CloseHandle(g_hSemaphore);
프로그램 종료시 세마포어를 해제한다.

DoThread() 쓰레드 내부에서는 다음과 같이 사용한다.

unsigned int WINAPI DoThread( LPVOID lpData )

{

    LockSemaphore();

 

    static int count = 0;

    count++;

    OutputDebugPrintf( "***** Start Thread %d\n", count );

    Sleep( 100 );

    OutputDebugPrintf( "***** End Thread %d\n", count );

 

    //이벤트에 의해 쓰레드 종료를 설명하기 위한 예제

    for(int  n=0; n < 100; ++n )

    {

        if( WaitForSingleObject( g_hStopEvent, 0 ) == WAIT_OBJECT_0 )

            break;

    }

 

    UnLockSemaphore();   

    return 0;

}

세마포어를 사용하지 않는다면 다음과 같이 결과가 나올것이다.

***** Start Thread 1
***** Start Thread 2
***** Start Thread 3
***** End Thread 3
***** End Thread 3
***** End Thread 3
세마포어를 사용하면 다음과 같이 원하는 결과가 나온다.

***** Start Thread 1
***** End Thread 1
***** Start Thread 2
***** End Thread 2
***** Start Thread 3
***** End Thread 3

  소스 : SemaphoreMain.cpp