CS/OS

[운영체제] Process Synchronization (2)

HYJJ 2022. 5. 23. 13:48

Initial Attempts to Solve Problem

 

공유 데이터를 접근하기 이전에 lock을 걸어 여러 프로세스가 동시에 들어가는 것을 막음. 

코드를 넣어서 critical section 해결하는 알고리즘 존재.


프로그램적 해결법의 충족 조건

 

- Mutual Exclusion 상호 배제  : 프로세스가 진행 중일 때 다른 프로세스가 critical section에 들어가지 않게 함.

- Progress 진행 : 아무도 critical section에 들어가지 않은 상태라면 프로세스가 critical section에 들어갈 수 있도록 해야 함.

- Bounded Waiting 유한 대기 : 기다리는 시간이 유한해야 함. 프로세스가 진행 중일 때 다른 프로세스가 들어가는 횟수를 제한. (지나친 starvation 피하기 위함.)


알고리즘 1

int turn : critical section에 들어가는 차례

Process P0 코드 (프로세스 P1도 이와 동일)

int turn;
turn = 0;
do {
	while(turn!=0):
    	// critical section
	turn = 1;
    	// remainder section
} while(1);

p0 입장에서 본인 입장에서 기다림. turn이 0으로 바꾸는 순간(p1이 1에서 0으로 바꿔줌.)

critical section 실행 후 나올 때 turn을 1로 바꿔줌. (상대방 차례로 바꿔줌.)

 

=> 들어가 있는 프로세스가 turn을 바꿔줘야 다른 프로세스가 들어갈 수 있기 때문에 progress 측면을 충족하지 못한 알고리즘

 

 

알고리즘 2

boolean flag : 본인이 critical section에 들어가고자 하는지

// 프로세스 Pi와 Pj

boolean flag[i] = false;
boolean flag[j] = false;

do {
	flag[i] = true;
    while(flag[j]) 
    	// critical section
		flag[i] = false;
        // remainder section
} while(1);

본인의 flag를 true로 만듬 -> 상대방 flag를 체크해서 true라면 기다리고, false라면 먼저 들어가서 critical section 실행 -> 실행 후 flag를 false로 바꿈.

 

=> 깃발만 들고 두 프로세스가 들어가지 않은 상태. 깃발을 내려놓는 행위는 나오는 행위에서 false로 처리함.

 둘다 true인 경우 아무도 critcal section을 실행하지 않는 상태. Mutual Exclusion 충족 X.

 

 

알고리즘 3 (Peterson's Algorithm)

알고리즘 1과 2 복합

// 프로세스 Pi, Pj
do {
    flag[i] = true;
    turn = j;
    while(flag[j] && turn ==j) {
    	// critical section
        flag[i] = false;
        // remainder section
    }
} while(1);

 상대방의 flag가 true이고 상대방의 차례라면? critical section 을 실행하고 flag를 false로 바꾸고 빠져나옴.

 

=> 3가지 프로그램적 해결법을 충족함. but Busy Waiting(spin lock) 문제 발생 (계속 CPU와 메모리를 쓰면서 wait)

 

 

Synchronization Hardware

하드웨어적으로 Test & modify를 atomic 하게 수행할 수 있도록 지원하는 경우 앞의 문제는 간단히 해결.

데이터를 메모리에서 읽는 동시에 쓰는 것이 하나의 instruction으로 가능하다면 쓰는 도중에 빼앗기지는 않을 것.

-> lock을 걸고 푸는 것이 해결될 수 있음.

 

Test_and_set(boolean lock) {
    // lock check -> if(!lock) -> lock 걸고 들어감.
    // lock check -> if(lock) -> 기다림.
}

boolean lock = false;

// Process Pi
do {
	while(Test_and_Set(lock) {
    	// critical section
        lock = false;
        // remainder section 
    }
}

값을 읽는 작업과 set하는 과정을 atomic 하게 실현된다면 lock이 실행 됨.