세마포어(Semaphore)기반의 동기화
세마포어와 뮤텍스는 상당히 유사하다고 한다. 둘의 차이는 카운트(Count)기능이다. 세마포어는 카운트 기능이 존재하지만, 뮤텍스에는 존재하지 않는다.
뮤텍스에는 임계영역에 접근 가능한 쓰레드 개수를 조절하는 기능이 없다. 그러나 세마포어는 임계영역에 접근 가능한 쓰레드 개수를 조절하는 기능이 있다.
임계영역의 접근 허용 쓰레드 개수를 하나로 제한하기 위해 사용되는 세마포어를 가리켜 바이너리(Binary)세마포어 라고 한다. 바이너리 세마포어는 뮤텍스와 동일한 기능을 제공하게 된다.
세마포어 관련 함수
세마포어(세마포어 오브젝트)를 생성하는 함수
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount,
LONG lMaximumCount,
LPCTSTR lpName
);
1.lpSemaphoreAttributes : 보안 속성을 지정하기 위한 매개변수이다.
2.lInitialCount : 임계영역에 접근 가능한 쓰레드의 개수를 제한한다. 세마포어에서 가장 중요한 전달인자이다.
3.lMaximumCount : 세마포어가 지닐수 있는 값의 최대 크기를 지정한다. 이 값이 1이면 뮤텍스와 동일한 기능을 하는 바이너리 세마포어가 구성된다. 기본적으로 lInitialCount 로 전달되는 값보다 커야한다.
4.lpName : 세마포어에 이름을 붙이기 위해 사용한다.
세마포어를 생성할 때 lInitialCount의 값을 10으로 설정한다면 WaitForSingleObject함수가 총 열번 호출될 때까지 카운트가 하나씩 감소하며 함수를 반환한다. WaitForSingleObject함수가 열한번쨰 호출될때 세마포어 카운트가 0인 관계로 블로킹 상태에 빠진다. 세마포어 카운터가 0보다 크면 Signaled 상태이고 0이라면 Non-Signaled 상태가 되는것이다.
임계영역을 빠져나온 쓰레드는 ReleaseSemaphore 함수를 호출해야 한다. 이 함수는 세마포어 카운트를 증가시키는 역할을 한다.
BOOL ReleaseSemaphore(
HANDLE hSemaphore,
LONG lReleaseCount,
LPLONG lpPreviousCount
);
1.hSemaphore : 반환하고자 하는 세마포어의 핸들을 인자로 전달한다.
2.lReleaseCount : 증가시킬 값의 크기를 결정할 수 있다. 2를 전달할 경우 세마포어 카운트 2가 증가한다. 아주 특별한 경우가 아니라면 1을 전달하는 것으로 충분하다. 세마포어 생성시 결정한 최대 카운트 값(CreateSemaphore 함수 중 lMaximumCount)을 넘겨서 증가 시킬것을 요구하는 경우 카운트는 변경되지 않고 FALSE만 반환한다.
3.lpPreviousCount : 변경되기 전 세마포어 카운트 값(이 함수 호출을 통해서 증가하기 이전의 값)을 저장할 변수를 지정한다. 필요 없다면 NULL을 전달한다.
뮤텍스
뮤텍스에서는 뮤텍스락을 하나의 쓰레드만 얻을 수 있다. 즉, 하나의 쓰레드 만이 크리티컬 섹션에 접근가능하다.
세마포어
세마포어는 한순간에 크리티컬 섹션에 접근할 수 있는 쓰레드 개수를 지정해 줄 수 있다. 예를들어 동시에 3개의 쓰레드 접근하게 설정이 가능하다. 접근하는 쓰레드를 카운트 하는 기능이 세마포어에 있으며 ReleaseSemaphore함수는 이러한 카운트를 반환한다.
WaitForMultipleObject 함수가 관찰할 수 있는 최대 커널 오브젝트 수는 MAXIMUM_WAIT_OBJECTS(현재 64개)로 제한된다.
'Programming > Windows System Programming' 카테고리의 다른 글
실행순서 동기화 - 이벤트 기반 동기화 (0) | 2020.08.01 |
---|---|
커널모드 동기화(Synchronization In kernel Mode) - 이름있는 뮤텍스(Named Mutex) (0) | 2020.07.31 |
커널 모드 동기화(Synchronization In kernel Mode) - 뮤텍스(Mutex) (0) | 2020.07.30 |
유저 모드 동기화(Synchronization In User Mode) (0) | 2020.07.29 |
쓰레드 동기화 (0) | 2020.07.28 |