공유 데이터의 동시 접근 상황에서 데이터 불일치가 발생할 수 있기 때문에 일관성을 유지하기 위해 프로세스 간의 실행 순서를 정해주는 메커니즘이 필요하다.
공유된 자원에 여러개의 프로세스가 동시에 접근할 때 발생하는 문제.
ex) 공유자원에 count라는 변수가 있을 때, 프로세스 a에서는 count--, 프로세스 b에서는 count++을 해주었을 때 실행 순서에 따라 값이 달라지는 경우
race condition을 막기 위해 concurrent process는 동기화 되어야한다.
Critical Section이란 공유 데이터를 접근하는 코드.
공유 데이터를 접근하는 코드가 실행중이라면 CPU가 뺏겨서 다른 프로세스에 CPU가 넘어가더라도 다른 프로세스의 공유 데이터를 접근하는 Critical Section에 들어가지 못하도록 해야한다.
do {
entry section - 여러 프로세스가 동시에 critical section에 들어가지 못하도록 lock
critical section - 공유 데이터를 접근하는 코드
exit section - lock 풀어서 다른 프로세스가 critical section에 들어갈 수 있도록
remainder section
} while(1);
do {
while(turn != 0); - 자기 차례가 될 때 까지 기다린다.
critical section
turn = 1; - 다음 차례로 넘겨준다.
remainder section
} while(1);
Mutual Exclusion은 만족하지만 Progress를 만족하지 못한다.(예를 들어 P0은 critical section에 100번 들어가야하고, P1은 1번만 들어가도 된다고 하면 P0이 100번 들어갈 수 없다. P1이 진행되어야지만 P0 차례로 넘어갈 수 있기 때문이다.
boolean flag[2]; - 각 프로세스마다 flag가 존재. critical section에 들어가고자 하는 상태를 나타냄. 초기에는 모두 false
do {
flag[i] = true; - critical section에 들어가고자 하는 의사를 나타냄
while(flag[j]); - 상대방 flag를 체크
critical section
flag[i] = false; - 사용 완료를 나타냄
remainder section
} while(1);
Mutual Exclusion은 만족하지만 Progress를 만족하지 못한다.(예를 들어 Pi가 flag를 true로 바꾸고 바로 CPU를 빼앗겨 Pj에 CPU가 넘어가면 Pj도 flag를 true로 바꿨는데 이미 Pi의 flag가 true이므로 아무도 critical section에 없더라도 아무 프로세스도 critical section에 들어갈 수 없다.)
do {
flag[i] = true; - critical section에 들어가고자 하는 의사를 나타냄
turn = j; - 상대방 turn으로 바꿔줌
while(flag[j] && turn == j); - 상대방이 flag를 들고 있고 동시에 상대방 차례인 경우만 기다림
critical section
flag[i] = false; - 사용 완료를 나타냄
remainder section
} while(1);
모든 조건을 만족함. 그러나 Busy Waiting(spin lock) 문제가 발생(상대 프로세스가 critical section에 있는 경우 본인은 while문을 계속 돌고 있다.)