* 세마포어 ( Semaphore )
=> Wait( ) , Signal( ) 신호 방식을 통해서 하나 이상의 프로세스 / 쓰레드가
임계 구역에 접근 가능하도록 하는 장치.
이진 세마포어 ( Binary semaphore ) : 세마포어 변수 값이 0 or 1 을 가진다.
계수 세마포어 ( Counting semaphore ) : 초기값은 가능한 자원의 수로 정해지며 범위는 정해져있지 않다.
=> 여기서 말하는 자원이라함은 컴퓨터에서의 자원 이다.
예를 들면, H/W 인 CPU, 프린터, 혹은 쓰레드가 함께 접근할 수 있는 데이터 등이 되겠다.
=> 쓰레드가 사용할 수 있는 자원의 개수 ( R ) 가 없다면
대기 큐에 삽입해 Sleep 시키고 다른 쓰레드의 작업이 끝났을 때,
대기큐에서 Sleep 하고 있던 쓰레드를 깨운다.
* 뮤택스 ( Mutex ) 와 세마포어 ( Semaphore ) 의 차이점
1. 권한
뮤택스의 Lock 이 가지는 임계구역 권한은 Lock 을 가진 쓰레드에게 있다.
자신이 구역을 원할 때 나올 수 있다. ( Unlock )
외부에 있는 어떤 다른 쓰레드의 영향을 받지 않는다.
세마포어는 해당 자원에 들어가는 쓰레드에게 권한을 부여한다고 보기 어렵다.
각기 다른 쓰레드가 접근할 수 있는 원자적 변수가 존재한다.
해당 원자적 변수가 다른 쓰레드들에게도 영향을 줄 수 있다.
2. 범위
뮤택스의 Lock 은 구역 안에 하나의 쓰레드만 들여보냄으로
하나의 쓰레드가 모든 구역을 제어한다.
세마 포어는
원자적 변수 ( Intiger ) 를 통해 다수의 쓰레드를 해당 구역에 들여보낼 수 있다.
같은 역할을 하는 공유 자원이 여러 개일 때 유용할 수 있다.
=> 물론,
뮤택스처럼 하나의 쓰레드가 들어가도록 구현 가능 하다.
* Monitor
=> 대표적 예로, 생산자 & 소비자 패턴을 들 수 있다.
=> Lock 보다 더 높은 단계의 동기화 형태.
=> 조건을 만족할 때까지 기다리게하는 역할로 Condition Variable 을 사용한다.
=> 'Condition Variable ( CV )' 는 개념적으로 '쓰레드의 큐' 이다.
lock 을 잡은 후 조건에 부합하면 통과시키고
조건에 맞지 않다면 'lock 을 풀고' 대기 큐에 넣는다.
즉,
중요한 것은 조건을 만족하면 해당 쓰레드가 실행되고
조건을 만족하지 않으면 해당 쓰레드가 'Unlock 후' 대기 큐에 'Sleep' 되어지는 것이다.
=> Producer 들이 모두 일을 끝낸 시점에서는
대기 큐에 있는 쓰레드들 모두를 깨우기 위해 Notify_all 을 수행해야 한다.
그렇지 않으면 대기 상태에 있는 쓰레드들을 메인 함수 혹은 호출한 쪽의 함수에서
계속 기다리게 될 것이다.
=> Busy Waiting ( 무한정 대기 ) 안정적이지만
문맥 교환의 비용이 들 수 있다.
참고 자료
'운영체제 & 컴퓨터구조' 카테고리의 다른 글
[OS] #13. RPCs ( Remote Procedure Calls ) (0) | 2022.10.22 |
---|---|
[OS] #12. 가상 메모리 ( Virtual Memory ) (0) | 2022.09.16 |
[OS] #10. mutex lock & 스핀락 ( Spinlock ) & CAS ( Compare-And-Swap ) (0) | 2022.09.14 |
[OS] #9. 원자성 ( atomic ) & 가시성 ( visibility ) & 코드 재배치 (0) | 2022.09.13 |
[OS] #8. 공유 자원 & 임계 구역 ( Critical Section ) (0) | 2022.09.12 |