Concurrency: 병행 제어
<Race Condition: 경쟁 상태>
A가 ++하는 동안 B가 count 가져가서 -1 한다면 -1뺀 결과만 저장된다. 원랜 0 저장되어야 하는데...
S-Box(Memory Address Space)를 공유하는 E-Box(CPU Process)가 여럿 있는 경우 Race condition(경쟁상태)의 가능성이 있다. 즉 여러 주체가 하나의 데이터에 동시 접근 하려고 할 때 경쟁 상태의 가능성이 있는 것이다.
* E - box?
CPU Process: MultiProcessor System, 공유 메모리를 사용하는 프로세스들. 커널 내부 데이터를 접근하는 루틴들 간 예) 커널모드 수행 중 커널모드로 다른 루틴 수행할 때)
<OS에서 race condition은 언제 발생하는가?>
1. 커널 수행 중 인터럽트 발생 시
2. 프로세스가 시스템 콜을 하여 커널 모드로 수행중인데 문맥 교환이 일어나는 경우 (또 커널 데이터를 접근해야 하기 떄문에)
3. 멀티프로세서에서 shared data 내의 kernel data
1. 커널 수행 중 인터럽트 발생 시
※ 커널 모드 running 중 interrupt가 발생하여 인터럽트 처리 루틴이 수행 -> 양쪽 다 커널 모드이므로 kernel address space를 공유하게 된다. 따라서 작업이 다 끝난 뒤에 interrupt를 받아들이고 작업중엔 무시하게 된다.
2. 프로세스가 시스템 콜을 하여 커널 모드로 수행중인데 문맥 교환이 일어나는 경우 (또 커널 데이터를 접근해야 하기 떄문에)
원래 두 프로세스의 address space 간에는 data sharing이 없다.
그러나 system call을 하게 되면 kernel address space의 data를 access하게 된다(share)
따라서 이 작업 중에 CPU를 선점 당하면 경쟁상태(race condition)이 발생한다.
Pa,Pb 둘다 count 1씩 증가시키니까 총 2 증가한 값이 반영되어야 하는데 Pa의 1 증가된 값만 반영된다.
해결책: 커널모드에서 수행중일 때에는 cpu를 preempt 하지 않는다. 커널모드에서 사용자 모드로 돌아갈 때 preempt한다.
3. 멀티프로세서에서 shared data 내의 kernel data
어떤 cpu가 마지막으로 count를 store 했는가 -> race condition
멀티 프로세서의 경우 인터럽트를 가능/불가능하게 하는걸로 해결되지 않는다.
해결방법 1: 한 번에 하나의 cpu만이 커널에 들어갈 수 있게 하는 방법
해결방법 2: 커널 내부에 있는 각 공유 데이터에 접근할 때마다 그 데이터에 대한 lock / unlock을 하는 방법(카피해가기 전에 데이터에 락을 걸어서 다른 cpu가 변경 못하게 막음)
<Process Synchronization 문제>
공유 데이터의 동시 접근(concurrent access)은 데이터의 불일치문제(inconsistency)를 발생시킬 수도 있다.
* 일관성(consistency) 유지를 위해서는 협력 프로세스 (cooperating process)간의 실행 순서를(orderly execution)를 정해주는 메커니즘이 필요하다.
* Race Condition(경쟁상태)
- 여러 프로세스들이 동시에 공유 데이터를 접근하는 상황
- 데이터의 최종 연산 결과는 마지막에 그 데이터를 다룬 프로세스에 따라 달라진다.
- 경쟁 상태를 막기 위해서는 concurrent process는 동기화(synchronize) 되어야 한다.
그런데 여기서 한가지 주의할 점이, 단순히 프로세스 실행 중 context switch가 발생하는 것이 문제가 아니라, 프로세스는 각자의 주소공간이 잇는데 이를 벗어난 shared data 이거나 커널 주소공간 또는 커널 코드일 경우에 문제가 되는 것이다.
<The Critical-Section Problem: 임계구역>
* n개의 프로세스가 공유 데이터를 동시에 사용하기를 원하는 경우
* 각 프로세스의 code segment에는 공유 데이터를 접근하는 코드(critical section)가 존재한다.
Problem
-하나의 프로세스가 critical section에 있을 때 모든 프로세스는 임계구역에 들어갈 수 없어야 한다.
<Initial Attempts to solve Problem>
두 개의 프로세스가 있다고 가정 P0, P1
프로세스들은 수행의 동기화(Synchronize)를 위해 몇몇 변수를 공유할 수 있다. -> Synchronization variable
<프로그램적 해결법의 충족 조건>
* Mutual Exclusion (상호 배제) (배타적)
- 프로세스 Pi가 크리티컬 섹션 부분을 수행 중이면 다른 모든 프로세스들은 그들의 크리티컬 섹션에 들어가선 안된다.
* Progress (진행)
- 아무도 크리티컬 섹션에 있지 않은 상태에서 크리티컬 섹션에 들어가고자 하는 프로세스가 있으면 크리티컬 섹션에 들어갈 수 있게 해줘야 한다.
* Bounded Waiting (유한 대기)
- 프로세스가 크리티컬 섹션에 들어가려고 요청한 후부터 그 요청이 허용될 때까지 다른 프로세스들이 크리티컬 섹션에 들어가는 횟수에 한계가 있어야 한다. -> startvation 발생하면 안된다는 소리 프로세스 1,2,3 있는데 1,2만 맨날 들어가면 3은 언제 들어가...
* 가정
모든 프로세스의 수행 속도는 0보다 크다
프로세스들 간의 상대적인 수행 속도는 고려하지 않는다.
<algorithm 1>
이 알고리즘의 문제는 Mutual Exclusion은 만족하나 Progress를 만족하지 않는다는 점이다. 즉 과잉 양보가 발생하게 된다. 반드시 한번씩 교대로 들어가야 한다. 만약 특정 프로세스가 더 빈번히 critical section에 들어가야 한다면?
<algorithm 2>
이 알고리즘의 문제점은 Mutual Exclusion은 만족하나 Progress를 불만족 한다. 물 다 2행까지 수행했다면 끊임없이 양보하는 상황이 발생할 수 있다. 만약 flag[0] = true에서 cpu를 뺏겨서(타이머 인터럽트) process 2로 cpu가 넘어갔는데 2도 flag true로 바꿔주고 while문 들어가려니까 flag 0 이 true라서 대기하다가 타이머 인터럽트 걸려서 cpu 빼앗기고 1도 2가 flag 들었으니까 또 무한대기하고 아무튼 이렇게 수행이 이루어지지 않을 수도 있다.
<algorithm 3>
이 방법은 3가지 조건을 모두 만족한다. (Mutual Exclusion, Progress, Bounded Waiting)
근데 단점이 Busy waiting(=spin lock)이다 while문을 계속 체크하면서 기다리다보니 계속 cpu와 메모리 자원을 잡아먹게 되어서 비효율적이다.
<Synchronization Hardware>
하드웨어적으로 Test & Modify를 atomic하게 수행될 수 있도록 지원하는 경우 앞의 문제는 간단하게 해결될 수 있다.
'CS > operating system' 카테고리의 다른 글
File System (1/1) (0) | 2021.02.28 |
---|---|
Process Synchronization: 프로세스 동기화 (2/2) (0) | 2021.02.28 |
Deadlock: 교착 상태 (2/2) (0) | 2021.02.26 |
Deadlock: 교착 상태 (1/2) (0) | 2021.02.25 |
Disk Management: 디스크 관리 (2/2) (0) | 2021.02.24 |