세마포어는 뮤텍스와 유사한 동기화 객체이다?

 

-      뮤텍스는 하나의 공유 자원을 보호하기 위해 사용하지만 세마포어는 제한된 일정 개수를 가지는 자원을 보호하고 관리한다.

 

 

세마포어는 사용가능한 자원의 개수를 카운트하는 동기화 객체이다?

        

-      유효자원이 0이면 즉 하나도 사용 할 수 없으면 세마포어는 비신호상태가 되며 1이상이면, 즉 하나라도 사용할 수 있으면 신호상태가 된다.

 

 

 

신호상태

스레드의 실행을 허가하는 상태이다.

신호상태의 동기화 객체를 가진 스레드는 계속 실행할 수 있다. (신호등의 파란불)

비신호상태

스레드의 실행을 허가하지 않은 상태이다.

신호상태가 될 때까지 스레드는 블록된다. (신호등의 빨간불)



세마포어 개념을 위한 예)

 

-      네트워크를 통해 프로그램을 다운받는 프로그램을 만든다.

 

n  동시에 여러 개의 자료를 다운로드 받는 것이 가능하기는 하지만 별로 효율적이지는 않다.

n  어차피 네트워크의 대역폭은 정해져 있는 것이므로 한꺼번에 다운로드 받는다고 해서 빨라지는 것도 아니고 그렇다고 순서대로 받는 것은 불편하다.

n  동시에 받되 최대 3개까지만 동시 다운로드가 가능하도록 하고싶다.

n  실제 다운로드 툴이나 웹 브라우저도 일정 개수까지만 동시 다운로드를 지원한다.

 

 

 

 

이경우 자원이란 다운로드 권한이라 표현할 수 있을 것이며 세마포어는 이 권한을 카운트 한다. 세마포어의 초기값을 3으로 설정하고 사용자의 요구가 있을 때마다 다운로드 스레드를 생성한다. 스레드에서는 WaitForSingleObject함수를 호출하여 자신이 사용할 수 있는 권한이 아직 남아 있는지 검사해 보고 가능하다면 다운로드 루프로 진입한다. 이때 대기 함수는 세마포어의 카운트를 1감소시켜 자원이 하나 줄어들었음을 기록한다.

 

두번째, 세번째 스레드가 다운로드를 시작하면 세마포어의 카운트는 0이 되며 비신호상태가 된다. 그러면 이후부터 생성되는 스레드는 다운로드 루프로 진입하지 못하고 자원이 사용가능해질 때 까지 대기하게 된다. 대기중에 첫번 째 스레드가 다운로드를 완료하면 세마포어를 풀 것이고 그러면 세마포어는 다시 1증가하여

신호상태가된다.

 

 

 

세마포어 함수정리

 

 

 

세마포어 생성함수

HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG llnitialCount, Long lMaximumCount, LPCTSTR lpName);

 

lpSemaphoreAttributes

보안속성

llnitialCount

초기값(최대사용개수에 대한 값)

lMaximumCount

최대사용개수(몇 개의 스레드를 실행시킬수 있나)

lpName

이름

첫번째 , 네번째 인자는 프로세스간의 동기화에 사용된다. 한 프로세스에서만 사용 할 시 NULL 값을 주면된다.

 

 

DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);

 

hHandle

하나의 동기화 객체가 신호상태가 되기를 기다린다.

dwMilliseconds

타임 아웃 시간

<dwMilliseconds>

1/1000초 단위로 지정하는데 이 시간이 경과하면 설사 동기화 객체가 비신호상태이더라도 즉시 리턴함으로써 무한 대기를 방지한다. 타임 아웃을 INFINITE로 짖어하면 신호상태가 될 때까지 무한정 대기한다.

 

 

 

WaitForSingleObject 리턴값

 

WAIT_OBJECT_0

hHandle 객체가 신호상태가 되었다.

WAIT_TIMEOUT

타임 아웃 시간이 경과하였다..

WAIT_ABANDONED

포기된 뮤텍스

 

 

 

세마포어의 카운트를 증가시켜주는 함수

 

BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount);

 

hSemaphore

자원을 반환할  세마포어

lReleaseCount

자신이 사용한 자원의 개수를 알려준다.

lpPreviousCount

이전 카운트를 리턴받기 위한 참조 인수

세번째 인자는 이 값에 관심이 없으면 NULL을 넘기면 된다.

 

함수 사용 예제

프로시저실행시

HANDLE hSem;

hsem = CreateSemaphore(NULL, 3, 3 , NULL);

 

마우스왼쪽버튼클릭시

HANDLE hThread;

hThread = CreateThread(NULL, 0, ThreadDownLoad, NULL, 0 , &ThreadID);

 

스레드 진입시

// 다운로드 화면표시 초기화

WaitForSingleObject(hSem, INFINITE);

// 다운로드 실행화면 표시

설명

-      같은 프로세스 내에서 사용할 것이므로 이름을 줄 필요는 없으며 보안 속성도 지정하지 않았다.

-      다운로드 가능 최대 개수는 3으로 설정했으며 처음부터 3개의 자원이 다 사용 가능하므로 초기값도 3이다.

-      왼쪽버튼클릭시 스레드가 생성되고 다운로드 실행화면이 표시된다. 네번째 클릭하게되면  해당 스레드는 WaitForSingleObject에서 대기하다가 어느 스레드가 종료되면 세마포어가 신호상태로되고 기다리던 스레드는 실행하게된다.



출처 - 윈도우즈 API 정복 , 한빛미디어

'API & MFC > API & 시스템프로그래밍' 카테고리의 다른 글

스레드  (0) 2010.01.24
이벤트  (0) 2010.01.24
파일매핑 사용순서  (0) 2010.01.24
Dll이란?  (0) 2010.01.24
파이프 추가내용  (0) 2010.01.20
Posted by 아몰라