세마포어
세마포어(Semaphore)는 임계영역에 진입(실행) 가능한 쓰레드의 수, 즉 정원을 제한하므로써 공유자원을 보호하는 방식이다.
공유자원의 개수를 나타내기도 하는 입장 가능한 쓰레드의 수는 변수(int sem)로 관리하는데 이 변수에 특별한 명칭을 부여하여 세마포어라 한다.
???/ 프로세스간 메시지 전송 용도
1. 세마포어 구현의 초안
SuperM :: [OS] 4. 프로세스 동기화 (Process Synchronization) (tistory.com)
세마포어를 가지고 공유자원을 보호하는 기본 구현은 아래의 예와 같이 Busy-Waiting(바쁘면-대기) 방식으로 부터 시작한다.
변수 sem이 임계영역에 대해 입장 가능한 쓰레드의 개수를 나타내고 있으며, 새로 입장하고자 하는 쓰레드는 sem>0 인 정수일때만 임계영역에 진입 할 수 있다.
global int sem=1; | ← sem 사용가능한 공유자원의 개수, sem=0 접근금지신호, sem>0 접금가능신호 |
void momo(void ) { while(s<=0) sem–; //세마포어 wait 구현 momo 쓰레드의 공유자원 액세스(임계영역); sem++; //세마포어 signal 구현 } |
void toto(void ) { while(s<=0) sem–; // 공유자원의 사용권이 1개 이상일때 까지 무한 대기 toto 쓰레드의 공유자원 액세스(임계영역); sem=sem++; // 공유자원의 사용권을 1 중가시켜, 다른 쓰레드가 임계영역을 실행할 수 있도록. } |
Busy-Waiting 방식은 MCU 자원을 계속해서 사용한다는 단점이 있지만 짧은 시간 내에 자원을 점유할 수 있다는 자신이 있는 경우 유용하다.
2. 세마포어 구현의 보완
통상 RTOS 시스템에서는 Busy Waiting 방식을 보완하여 쓰레드에 대한 suspend, sleeping 또는 blocking와 같은 기능을 제공하고 있다.
void momo(void ) { wait(sem); momo 쓰레드의 공유자원 액세스(임계영역); signal(sem); } |
void toto(void ) { wait(sem); toto 쓰레드의 공유자원 액세스(임계영역); signal(sem); } |
type struct{ int count; struct thread *list-in-q; }sem; |
count=semaphore list-in-q=wait queue |
wait(sem){ sem.count–; if(sem.count<0) block(); } |
쓰레드가 임계영역에 진입을 못하는 조건에서 쓰레드를 Block 대기상태/Sleep 상태로 빠지게 만든다. 쓰레드하나를 list-in-q에 집어 넣음. |
signal(sem){ sem.count++; if(sem.count<=0) { wakeup(); } } |
wakeup(): list-in-q에서 쓰레드 하나를 꺼냄 |
3. 문제해결 확인