Semaphore
-
앞의 방식들을 추상화시킴!
-
추상자료형(ADT): 추상 자료형은 object & operation이 있어야.
-
세마포어: 일종의 추상 자료형! 추상 자료형 S
-
정수 형태!의 변수 (integer variable)
- 아래 두 가지 atomic 연산에 의해서만 접근 가능
-
세마포어는 왜 써?
- 락을 걸고 풀고
- 공유 자원을 획득/반납하는 걸 세마포어가 처리! 세마포어 변수에 대해 정의되는 연산: p연산과 v연산
-
세마포어 연산 예시 ⇒ 이건 busy waiting 방식.
- 세마포어 자료형 변수 S에 들어가는 값은 자원의 갯수라고 생각하면 된다.
- if S = 5 면 자원 5개.
- 여기서 p 연산해주면 자원 하나 가져가서 4개.
- P 연산 5번 해서 다섯 개의 프로세스가 자원을 가져갈 수 있고
- V연산: 자원 다 사용하고 나서 내려놓는. V 연산 5번 하면 다시 S=5가 된다.
- lock을 걸고 푸는 과정: 세마포어 변수 값이 1인 경우를 생각해보자.
- P연산하면 lock을 거는 과정
- v 연산: lock을 푸는 과정.
-
P연산 로직
- S값이 0 이하인 동안에 while문 돌면서 아무 것도 안하고 기다려. (이때는 자원이 하나도 없는 상황. s가 0이니까.)
- S값이 1이 되면(누군가 자원을 반납하면) 그때 s값을 1 빼고 냉큼 자원을 자기가 가져간다!
-
V연산 로직
- 자원 사용하고서 끝나면 V연산 진행해서 s값을 증가시키고 자원을 내놓는다.
-
이때, P연산과 V연산은 atomic하게 연산 수행된다고 가정
- 세마포어는 구체적인 구현이 아닌 추상적인 정의.
- 어떤 식으로 atomic하게 연산되는지는 패스(나중에 코드로 짤듯) - 여기서 atomic하다는 건 더이상 쪼개지지 않는다는 것을 의미.
- 자원이 있으면 가져가고 없으면 기다린다. 이 과정이 atomic하게 이뤄져야.
-
busy-wait 문제는 여전히 생김.
Critical Section of n Processes
- critical section 문제에다가 세마포어를 사용하게 되면?
- 세마포어 변수 mutex(mutual exclusion)를 1로 놓고 lock을 걸 때, critical section에 들어갈 때는 P 연산, 빠져나올 때는 V연산 진행.
- 세마포어가 지원되면 P연산과 V연산만 해주면 됨. 구현은 시스템 몫!
- 사용자가 일일이 알고리즘을 짜는 게 아니라 추상 자료형 형태로 제공받고, 프로그래머는 세마포어를 이용해 프로그램하면 훨씬 간단해져!
- 이 방법을 사용하면 → 누군가 critical section에 들어갔을 때, P연산 하면서 while문 돌다가 할당 시간 끝나서 cpu 반납하는 busy wait(spin-lock)이 여전히 발생할 것!
- ⇒ busy-wait(=spin lock)은 효율적이지 X
- Block & Wakeup 방식으로 구현하면 효율적(이게 sleep lock!) 잠들어버리게 하는 방식.
Sleep lock(=Block & wakeup)
- 어떤 프로세스가 cpu에서 작업하다가 I/O 작업해야 되면 blocked 상태가 된다. cpu 얻을 권한 자체가 없어짐. 디스크 I/O가 끝나면 ready queue로 돌아올 수 있는 권한이 생겨.