Search
💾

[OS] Process Synchronization 2

참고 강의
contents

Semaphores

추상 자료형
정수값
두 가지 atomic 연산에 의해서만 접근 가능 - P(S), V(S)
세 개의 특수한 명령들만 접근할 수 있게 허용되는 보호된 변수
 공유 자원을 획득하고 반납하는데 세마포어가 처리해준다.
초기화 명령(optional)
P(S) : 공유 데이터를 획득하는 과정 - wait, down
V(S) : 공유 데이터를 반납하는 과정 - signal, up
busy-wait(= spin lock) 문제는 계속 발생한다.
세마포어에 대한 명령들은 각각 분리되지 않고 수행될 수 있도록 구현해야 하며, 같은 세마포어에 대해서 동시에 실행되지 못한다. → P(S) 중이라면 V(S) 불가능
세마포어를 활용하면 상호배제뿐만 아니라 프로세스 간의 동기화도 쉽게 구현 가능

Critical Section of n Processes

semaphore mutex; initially 1 do { P(mutex) critical section V(mutex) remainder section } while(1);
C
복사
전에 있던 Algorithm과는 다르게 P, V 연산만 해주면 된다.
→ 구연을 어떻게 할 것인지는 시스템의 몫
Block & Wakeup 방식(= sleep lock)으로 구현될 수 있다.
lock를 못 얻으면 쓸데없이 CPU를 사용하는 것이 아니고 잠들어 버린다.

Block / Wakeup Implementation

typedef struct { int value; // 세마포어 변수값 struct process *L; // 잠든 값들 연결하는 Queue } semaphore;
C
복사
Block : 커널은 block을 호출한 프로세스를 suspend 시킴. 이 프로세스의 PCB를 semaphore에 대한 wait queue에 넣음
Wakeup : block된 프로세스 P를 wakeup시킴. 이 프로세스의 PCB를 ready queue로 옮김
당장 세마포어를 얻을 수 없는 상태라면 해당 프로세스를 Block → 누군가가 쓰고 반납을 하게 되면 Block된 프로세스 중에 하나를 깨워서 Wakeup 시킴
P(S)
S.value--; if(S.value < 0) { add this process to S.L; block(); }
C
복사
자원의 여분이 없다면 block 된다.
V(S)
S.value++; if(S.value <= 0) { remove a process P from S.L; wakeup(P); }
C
복사
반납을 하고 끝내는 것이 아니고 이 자원을 기다리면서 잠든 프로세스를 깨우는 작업이 필요
자원을 내놓았음에도 음수라는 것은 잠든 프로세스가 있다는 것
여기서의 S.value는 전과 다른 의미를 가진다.(상황을 나타냄)
양수 : 자원의 여분이 있음
음수 : 기다리는 프로세스들이 잠들어 있음

Busy-wait v.s. Block/wakeup

일반적으로 Block/wakeup이 더 효율적이다.
CPU를 더 의미있게 이용하기 때문에
But, Block/wakeup overhead 존재
Ready 상태에서 Sleep 상태로 바꾸고, Sleep 상태에서 Ready 상태로 바꾸는 일이 필요 → Overhead가 발생
Section의 길이가 짧은 경우 - busy-wait하는 것이 오버헤드가 덜 듦
Section의 길이가 긴 경우 - while문만 돌면서 낭비되는 CPU 시간이 많기 때문에 block/wakeup이 필수
추가
Block/wakeup : CPU의 낭비를 막지만 Wake한 P가 바로 CPU를 받아서 Running하지 못한다. 즉각 반응이 늦어진다!
조건이 만족되면 Wake시켜서 Ready Queue로 보낸다. Ready의 프로세스들과 경쟁을 해서 CPU를 받아야 하기 때문.
커널이 개입하기 때문에 Ready로 바꾸는 동안 CPU 시간을 OS가 사용
Busy-wait : CPU를 wait용도로 busy시키기에 유용한 곳에 활용하지 못한다는 문제 발생 → CPU 낭비
wait한 상황이 만족되면 while문에서 벗어나서 critical section에 바로 진입 가능하다.

Two Types of Semaphores

1.
Counting semaphore
: 도메인이 0 이상인 임의의 정수값
자원의 갯수가 여러개인 경우(여분이 있으면 가져다 쓸 수 있는)
주로 resource counting에 사용
2.
Binary semaphore(= mutex)
: 0 또는 1 값만 가질 수 있는 semaphore
자원의 갯수가 하나인 경우
주로 mutual exclusion(lock/unlock)에 사용

Deadlock and Starvation

Semaphore에서 발생할 수 있는 문제
S를 획득하려면 영원히 기다려야 한다 → P0은 Q까지 다 사용하고 나서 S를 내놓을 수 있다.
영원히 조건을 충족하지 못하는 상태 → Deadlock !
Deadlock
: 둘 이상의 프로세스가 서로 상대방에 의해 충족될 수 있는 event를 무한히 기다리는 현상
해결법
자원을 획득하는 순서를 똑같이 맞춰주면 해결 가능하다.
Starvation
: indefinite blocking. 프로세스가 suspend된 이유에 해당하는 세마포어 큐에서 빠져나갈 수 없는 현상
특정 프로세스들만 자원을 자기들끼리 공유하면서 다른 프로세스는 영원히 자기 차례가 오지 못하게 하는 것