앞서 TAS를 통한 Atomic한 락 설정 방법을 공부했습니다. Atomic한 락 설정을 통해 Preemption으로 인한 이상현상 없이 임계구역을 보호하기 위해 운영체제는 몇가지 방법들을 사용합니다.
세마포어란, 다익스트라가 제안한 알고리즘으로, Busy Waiting으로 인한 성능저하 문제를 해결합니다.
기본적인 동작방법
Init(initS){
S = initS
}
P(){
if S > 0:
S-=1
else:
sleep()
}
V(){
if Waiting Process in Queue:
wakeup() # 다른 프로세스가 임계구역으로 접근하므로, S변수는 그대로!
else:
S+=1
}
Action(){
P()
//Critical Section
V()
}
세마포어의 특징: 임계구역 제한방식의 차이
Busy Waiting와과 Sleep-Wakeup을 통한 임계구역 제한에는 분명한 차이가 있습니다.
프로세스와 상태변화(https://blog.mglee.dev/blog/프로세스의-개념과-상태-변화/ 참고)에 대해 이해하고 있어야합니다.
Semaphore의 Sleep-Wakeup에서는 블로킹된 프로세스는 CPU를 잡아먹지 않습니다.
Spin Lock 방식은 블로킹된 프로세스가 CPU를 점유하며 아무동작도 하지 않습니다.
Busy Waiting Vs Sleep Wakeup ?
Sleep Wakeup 방법에서는 락을 획득하지 못해 대기하는 스레드가 Running state로 들어가는 일이 없으므로, Blocking으로 인한 CPU IDLE상태가 되지 않습니다. 따라서 일반적으로 성능이 더 좋은 Sleep-Wakeup방식을 사용합니다.
이진 세마포어와 카운팅 세마포어
세마포어에는 이진 세마포어, 카운팅 세마포어로 나뉩니다.
이진 세마포어는 세마포어변수가 1이므로, 하나의 스레드만 임계구역에 접근할 수 있어 임계구역에 대한 상호배제를 지켜주기 때문에, Mutex라고도 불립니다. (Mutual Exclusion의 약자)
카운팅 세마포어는 S(>1)개의 스레드가 임계구역에 접근할 수 있습니다. 카운팅 세마포어는 그 자체만으로 상호배제를 달성하지는 못합니다. 그러나 카운팅 세마포어를 적절히 사용하면 운영체제에서 발생하는 여러 동시성 문제를 해결할 수 있습니다. (Producer/Consumer 문제, 식사하는 철학자 문제 등)
OSTEP: Operating Systems: Three Easy Pieces - https://pages.cs.wisc.edu/~remzi/OSTEP/
HPC Lab. KOREATECH, OS Lecture- https://www.youtube.com/watch?v=es3WGii_7mc&list=PLBrGAFAIyf5rby7QylRc6JxU5lzQ9c4tN