Search
💾

[OS] Process Synchronization 1(2)

참고 강의
contents

Inital Attempts to Solve Problem

공유 데이터를 접근하는 코드 : Critical Section → 동시 접근으로 문제 발생
Entry Section를 통해서 lock를 걸어서 동시에 들어가는걸 막음
Exit Section를 통해서 unlock를 해서 다른 프로세스가 들어가도록 함

Critical Section문제를 풀기 위해서 만족해야하는 조건

[ 가정 : 모든 프로세스의 수행 속도는 0보다 크다 ]
[ 가정 : 프로세스들 간의 상대적인 수행 속도는 가정하지 않는다 ]
1.
Mutual Exclusion(상호 배제)
프로세스 Pi가 critical section 부분을 수행 중이면 다른 모든 프로세스들은 그들의 critical section에 들어가면 안 된다.
2.
Progress(진행)
아무도 critical section에 있지 않은 상태에서 critical section에 들어가고자 하는 프로세스가 있으면 critical section에 들어가게 해주어야 한다.
3.
Bounded Waiting(유한 대기)
프로세스가 critical section에 들어가려고 요청한 후부터 그 요청이 허용될 때까지 다른 프로세스들이 critical section에 들어가는 횟수에 한계가 있어야 한다.
Starvation이 생기지 않도록
ex. 3개의 프로세스가 critical section에 들어가야할 때, 2개의 프로세스가 계속 번갈아가면서 critical section를 사용하고 나머지 하나가 들어가지 못할 때 Bounded Waiting이 지켜지지 않았다고 볼 수 있다.
상호 배제 실현 조건
고급 언어의 instruction들이 단일 instruction이 아니기에 실행 도중에 CPU를 뺏기기 때문에 문제가 발생하게 된다.

Algorithm 1

turn : 누구의 차례인지 나타내는 변수
Process P0
do { while(turn != 0) critical section turn = 1 remainder section } while(1)
C
복사
Process P1
do { while(turn != 1) critical section turn = 0 remainder section } while(1)
C
복사
상대방이 critical section에서 빠져나올 때, 다른 프로세스가 critical section으로 들어갈 수 있게 된다.
Mutual Exclusion 만족 → 동시에 들어가는 일이 생기지 않기 때문에
Progress 불만족
다른 프로세스가 critical section에 들어갔다가 나와야지만 turn이 바뀌게 된다. 하지만 critical section에 들어가려는 빈도가 균일하지 않다면 계속 들어가고 싶은 프로세스도 turn을 상대방이 바꿔주지 않아서 안으로 들어가지 못하게 된다.
turn 이라는 변수가 있기 때문에 첫 turn이 정해져 있다. 비어있는 Critical Section은 바로 진입 가능하다는 조건을 불만족
누구든 연속해서 두 번 이상 진입이 불가능
실행 속도가 느린 프로세스의 속도에 의존적일 수 밖에 없다는 문제 발생
 Critical Section 문제 해결 불가

Algorithm 2

flag : critical section에 들어가고 싶은 의중을 표시하는 것, 프로세스 각각 가지게 된다.
critical section으로 들어가고 싶은 프로세스는 flag를 true로 만든다.
상대방도 critical section에 들어가고 싶다는 표시를 했다면 while에서 기다린다.
critical section에서 나올 때는 자신의 flag를 false로 만든다.
Process P0
do { flag[0] = true while(flag[1]) critical section flag[0] = false remainder section } while(1)
C
복사
Process P1
do { flag[1] = true while(flag[0]) critical section flag[1] = false remainder section } while(1)
C
복사
Mutual Exclusion 만족 → 동시에 들어가는 일이 생기지 않기 때문에
Progress 불만족
만약, flag[0]이 true가 된 상태에서 CPU를 뺏기면 다른 프로세스에서 critical section에 들어가고 싶어도 프로세스 0이 들어가 있다고 판단을 하여 while에서 기다리게 된다.
→ 프로세스 0이 다시 while문을 실행했을 때, 다른 프로세스도 flag[i]가 0이라서 결국 둘 다 양보하는 상황이 발생한다.(= Livelock)

Algorithm 3(Peterson’s Algorithm)

Dekker의 알고리즘이 있는데 이는 간결하게 만든 것이 Peterson’s Algorithm이다. Dekker 알고리즘의 단점을 해결하였다.
turn과 flag 변수를 모두 사용하는 알고리즘
Process P0
do { flag[0] = true turn = 1 while(flag[1] && turn == 1) critical section flag[0] = false remainder section } while(1)
C
복사
Process P1
do { flag[1] = true turn = 0 while(flag[0] && turn == 0) critical section flag[1] = false remainder section } while(1)
C
복사
중간에 CPU를 뺏긴다고 하더라도 문제를 내지 않는다. → 조건을 모두 충족
Busy Waiting(== spin lock) 발생
: 계속 CPU와 memory를 쓰면서 wait
→ 계속 쓸데없이 while문을 체크하는데에 CPU를 사용함. 비효율적인 방식.
문장 하나하나 실행중에도 CPU를 빼앗길 수 있기 때문에 소프트웨어적으로 복잡한 코드가 되었다.
n 프로세스 간의 상호배제를 위한 소프트웨어 기법들

Synchronization Hardware

이런 문제가 생겼던 이유는 데이터를 읽는것과 쓰는것을 하나의 instruction으로 할 수 없기 때문이다.
Test and set(a) : a라는 데이터 값을 읽어내고 a 데이터값을 1로 바꿔주는 instruction를 한 번에(atomic) 처리 → 하드웨어적
 이게 지원이 된다면 코드를 복잡하게 짜지 않아도 된다. 간결하게 바뀐다.
기계명령어를 활용하면 간단하고, 다중처리 시스템에서도 쉽게 쓸 수 있으며, 한 프로그램 내에서 서로 다른 변수를 사용하여 여러 개의 임계 영역도 지원할 수 있는 장점이 있다.
Synchronization variable: boolean lock = false; do { while(Test_and_Set(lock)); critical seciton lock = false remainder section }
C
복사
인터럽트 금지를 사용한 기법