병행제어
데이터의 접근




3. Multiprocessor에서 shared memory 내의 kernel data


shared data(공유 데이터)의 concurrent access(동시 접근)은 데이터의 inconsistency(불일치)를 발생시킬 수 있다.
Consistency(일관성) 유지를 위해서는 cooperating procee(협력 프로세스)간의
orderly execution(실행 순서)를 정의해주는 메커니즘이 필요하다.
Race Condition
race condition을 막기 위해서는 공존하 프로세스(concurrent process)가 동기화(Synchronize)되어야 한다.
n개의 프로세스가 공유 데이터를 동시에 사용하기를 원하는 경우
각 프로세스의 code segment에는 공유 데이터를 접근하는 코드인 critical section이 존재
문제점 : 하나의 프로세스가 critical section에 있을 때 다른 모든 프로세스는 critical section에 들어갈 수 없어야 함
do {
entry section
critical section
exit section
reminder section
} while(1);
Synchronization variable int turn; -> 어떤 프로세스의 차례인지를 나타내는 변수값으로 사용 initially turn = 0;
=> P1 can enter its critical section if(turn == i)
Process P0
do {
while (turn != 0); # My turn? 0은 자기자신
critical section
turn = 1; # Now it's your turn 1이 다른 프로세스
remainder section
} while(1);
do {
while (turn != 1); # My turn?
critical section
turn = 0; # Now it's your turn
remainder section
} while(1);
Synchronization variable boolean flag[2]; initially flag[all] = false; => No one is in CS (critical section)
Pi ready to enter its critical section if (flag[i] == true)
Process Pi
do {
flag[i] = true; # Pretend I am in (프로세스에 들어가고 싶다는 의사 표시)
while (flag[j]); # Is It also in? than wait (프로세스가 이미 점유되고 있는지 확인)
critical section
flag[i] = false; # I'm out now
remainder section
} while(1);
do {
flag[i] = true; # My intention is to enter ...
turn = j; # set to its turn
while (flag[j] && turn == j);
critical section
flag[i] = false; # I'm out now
remainder section
} while(1);
do {
while (Test_and_Set(lock));
critical section
lock = false;
remainder section
} while(1);
while(S <= 0) do no-op; # wait
S--;
누군가가 자원을 반납하면 S를 1 감소시키고 작업을 실행
추상적으로 연산을 구현해놓은 것
자원이 있으면 가져가는 것이고 없으면 while문을 돌면서 대기하는 것. (busy-wait은 발생하게 됨.)
S++;
Synchronization variable
semaphore mutex; # 추상 변수처럼 semaphore 정의
Process Pi;
do {
P(mutex);
critical section
V(mutex);
remainder section
} while(1);
typedef struct
{
int value; # Semaphore
struct process *L; # process wait queue
} semaphore;
block과 wakeup을 다음과 같이 가정
semaphore 연산이 이제 다음과 같이 정의됨.
S.value++; # 자원을 다 쓰고 나면 S.value 값 증가시키기 (반납)
if(S.value <= 0) {
remove a process P from S.L; # ready queue에서 삭제
wakeup(P); # 만약 잠들어 있다면, 프로세스 깨우기
}
S.value--; # Prepare to enter
if(S.value < 0) { # 자원 여분 X. Semaphore 획득 실패 (대기 상태)
add this process to S.L; # ready queue에 추가
block(); # block 상태
}