Chapter 6: Synchronization Tools
counter < BUFFER_SIZE 일 때 write
while (True) {
while (counter == BUFFER_SIZE) ; //do nothing
buffer[in] = nextProduced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
counter > 0 일 때 read
while (True) {
while (counter == 0) ; //do nothing
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
}
do {
<entry section> // 들어가는 문
critical section
<exit section> // 나가는 문
remainder section
} while (true);
Mutual Exclusion
Progress
Bounded Waiting
- 유한한 기다림
- starvation 발생 X
→ 모두 만족해야 critical section problem이 해결됨
충돌 발생 시 상대에게 먼저 양보
int turn
critical section에 들어갈 process
bool flag[i]
Pi가 들어갈 준비가 되었는지 여부
→ turn을 서로 양보해준다.
Mutual exclusion 만족
Pi : flag[j] == false
or turn == i
인 상태에서만 들어감
Pj : flag[j] == true
인 상태에서만 들어감
→ Pi, Pj는 동시에 들어갈 수 X
Progress 만족
flag[j] == true && turn == j
인 경우에만 멈춤 → busy waitingBounded waiting 만족
Peterson’s Solution 적용 어려움
atomic operation 이 필요
test_and_set()
compare_and_swap
![](https://velog.velcdn.com/images/jnary/post/15c9cbe8-57ab-40fc-b9f5-e63021ed88d8/image.png)
![](https://velog.velcdn.com/images/jnary/post/fa7024f1-257f-4faa-82fb-849bd7b240c8/image.png)
- expected = 0, new_value = 1
- test_and_set()과 동일, 같은 기능
→ Bounded waiting 보장 X
Bounded waiting 보장
사용 가능 X → busy waiting
사용 가능 → available = false로 변경 후 자기만 사용
acquire() {
while (!available)
/* busy wait */
available = false;
}
release() {
available = true
}
do {
<acquire lock>
/* ciritical section */
<release lock>
/* remainder section */
} while (true);
wait(S) {
while (S <= 0)
/* busy wait */
S--;
}
signal(S) {
S++;
}
S1 끝나야 S2 실행되도록
synch = 0 초기화
P1:
S1;
signal(synch);
P2:
wait(synch);
S2;
typedef struct {
int value; //semaphore 값
//음수 : 대기중인 프로세스 개수, 양수 : 이용가능한 자원 개수
struct process *list; //대기 중인 PCB 리스트 가리키는 포인터
} semaphore;
wait(semaphore *S) {
S -> value--;
if (S -> value < 0) {
add this process to S -> list;
block();
}
}
signal(semaphore *S) {[
S -> value++;
if (S -> value <= 0) {
remove a process P from S -> list;
wakeup(P);
}
}
→ Monitor : Simple Synchronization Tool
내부 변수는 오직 code를 통해서만 접근 가능
monitor내의 함수들은 한 번에 하나씩만 활성화 가능
monitor monitor_name {
function P1 (..) {...}
...
function Pn (..) {...}
Initialization code (..) {...}
}
}
X.wait()
호출한 프로세스 일시 중단
X.signal()
Signal and wait
Signal and continue
- Q : P가 모니터 떠날 때까지 대기
→ 둘 다 장단점 존재, 프로그래머가 결정
동기화 고려하다보면 deadlock, starvation 발생 가능
+) OS를 사용하는 목적