[OS] ๋ณํ์ ์ด
๋ฐ์ดํฐ์ ์ ๊ทผ
Race Condition
- ํ๋์ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฟ์ด ๋์์ ์ ๊ทผํ๋ ค๊ณ ํ ๋ ์๊ธฐ๋ ๋ฌธ์
OS์์ race condition์ ์ธ์ ๋ฐ์ํ๋๊ฐ?
1. kernel ์ํ ์ค ์ธํฐ๋ฝํธ ๋ฐ์ ์
Solution
- ํด๊ฒฐ์ฑ ์ปค๋์ ๊ณต์ ๋ณ์ Count ๋ณ์๋ฅผ ๊ฑด๋๋ฆฌ๊ธฐ ์ ์ ์ธํฐ๋ฝํธ ๋์ค์์ด๋ธํ๊ณ ๋๋๋ฉด ๋ค์ ์ธ์์ด๋ธํ๋ ๋ฐฉ์
2. Process๊ฐ system call์ ํ์ฌ kernel mode๋ก ์ํ ์ค์ธ๋ฐ context switch๊ฐ ์ผ์ด๋๋ ๊ฒฝ์ฐ
- PA๊ฐ CPU๋ฅผ ์ก๊ณ user mode์์ ์คํ์ด ๋๋ค๊ฐ ์์คํ ์ฝ์ ํด์ kernel mode๋ก ๋ค์ด์์ kernel์ ๋ฐ์ดํฐ์ธ counter ๋ณ์ ๊ฐ์ผ ์ฆ๊ฐ์ํค๋ ์์ค์ context switch๊ฐ ๋ฐ์
3. Multiprocessor์์ shared memory ๋ด์ kernel data
- ๋ฐฉ๋ฒ 1์ ๋ง์ ์ค๋ฒํค๋ ๋ฐ์ํ๊ฒ ๋จ -> ๋ฐฉ๋ฒ 2๊ฐ ์ข์ ๋ฐฉ๋ฒ์
Process Synchronization ๋ฌธ์
- ๊ณต์ ๋ฐ์ดํฐ(shared data)์ ๋์ ์ ๊ทผ(concurrent access)์ ๋ฐ์ดํฐ์ ๋ถ์ผ์น ๋ฌธ์ (inconsistency)๋ฅผ ๋ฐ์์ํฌ ์ ์์
- ์ผ๊ด์ฑ(consistency) ์ ์ง๋ฅผ ์ํด์๋ ํ๋ ฅ ํ๋ก์ธ์ค(cooperating process) ๊ฐ์ ์คํ ์์(orderly execution)๋ฅผ ์ ํด์ฃผ๋ ๋งค์ปค๋์ฆ ํ์
- Race condition
- ์ฌ๋ฌ ํ๋ก์ธ์ค๋ค์ด ๋์์ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ๋ ์ํฉ
- ๋ฐ์ดํฐ์ ์ต์ข ์ฐ์ฐ ๊ฒฐ๊ณผ๋ ๋ง์ง๋ง์ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฌ ํ๋ก์ธ์ค์ ๋ฐ๋ผ ๋ฌ๋ผ์ง
- race condition์ ๋ง๊ธฐ ์ํด์๋ concurrent process๋ ๋๊ธฐํ(synchronize)๋์ด์ผ ํจ
The Critical-Section Problem
- critical section : n๊ฐ์ ํ๋ก์ธ์ค๊ฐ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ๋์์ ์ฌ์ฉํ๊ธฐ๋ฅผ ์ํ๋ ๊ฒฝ์ฐ
- ๊ฐ ํ๋ก์ธ์ค์ code segment์๋ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ๋ ์ฝ๋์ธ critical section์ด ์กด์ฌ
Problem
- ํ๋์ ํ๋ก์ธ์ค๊ฐ critical section์ ์์ ๋ ๋ค๋ฅธ ๋ชจ๋ ํ๋ก์ธ์ค๋ critical section์ ๋ค์ด๊ฐ ์ ์์ด์ผ ํจ
Initial Attempts to Solve Problem
- ๋ ๊ฐ์ ํ๋ก์ธ์ค๊ฐ ์๋ค๊ณ ๊ฐ์ P0, P1
- ํ๋ก์ธ์ค๋ค์ ์ผ๋ฐ์ ์ธ ๊ตฌ์กฐ
do{
entry section
critical section
exit section
remainder section
} while(1);
- critical section์ ์ ๊ทผํ๊ธฐ ์ ์ entry section์์ lock ๊ฑธ๊ณ , exit section์์ lock์ ํด์
- ํ๋ก์ธ์ค๋ค์ ์ํ์ ๋๊ธฐํ(synchronize)๋ฅผ ์ํด ๋ช๋ช ๋ณ์๋ฅผ ๊ณต์ ํ ์ ์์
-> synchroniztion variable
ํ๋ก๊ทธ๋จ์ ํด๊ฒฐ๋ฒ์ ์ถฉ์กฑ ์กฐ๊ฑด
์๋ Algorithm๋ค์ด ๋ง์กฑํด์ผํ ์กฐ๊ฑด๋ค
- Multual Exclusion (์ํธ ๋ฐฐ์ )
- ํ๋ก์ธ์ค Pi๊ฐ critical section ๋ถ๋ถ์ ์ํ ์ค์ด๋ฉด ๋ค๋ฅธ ๋ชจ๋ ํ๋ก์ธ์ค๋ค์ ๊ทธ๋ค์ critical section์ ๋ค์ด๊ฐ๋ฉด ์๋จ
- Progress (์งํ)
- ์๋ฌด๋ critical section์ ์์ง ์์ ์ํ์์ critical section์ ๋ค์ด๊ฐ๊ณ ์ ํ๋ ํ๋ก์ธ์ค๊ฐ ์์ผ๋ฉด critical section์ ๋ค์ด๊ฐ๊ฒ ํด์ฃผ์ด์ผ ํจ
- Bounded Waiting (์ ํ๋๊ธฐ)
- ํ๋ก์ธ์ค๊ฐ critical section์ ๋ค์ด๊ฐ๋ ค๊ณ ์์ฒญํ ํ๋ถํฐ ๊ทธ ์์ฒญ์ด ํ์ฉ๋ ๋๊น์ง ํ๋ก์ธ์ค๋ค์ด critical section์ ๋ค์ด๊ฐ๋ ํ์์ ํ๊ณ๊ฐ ์์ด์ผํจ
Algorithm 1
do {
while(turn != 0); /* My turn? */
critical section
turn = 1; /* Now it's your turn */
remainder section
} while(1);
- critical section์ ๋ค์ด๊ฐ๊ธฐ ์ ์ ๋ด ์ฐจ๋ก์ธ์ง๋ฅผ ์ฒดํฌํ๋ค๊ฐ ์ฐจ๋ก๊ฐ์ค๋ฉด critical section์ ๋ค์ด๊ฐ์ ๊ณต์ ์ฝ๋๋ฅผ ์ํํ๊ณ ๋๋๋ฉด ์ฐจ๋ก๋ฅผ ์๋๋ฐฉ ์ฐจ๋ก๋ก ๋ฐ๊ฟ์ค
- turn์ ๋ฌ์ ๋์์ critical section์ ๋ค์ด๊ฐ๋ ๋ฌธ์ ๋ ํด๊ฒฐํ์์ง๋ง ๋ฐ๋์ ์์๋ฅผ ๊ต๋๋ก ๋ค์ด๊ฐ์ผ(swap-turn) ํ๋ ๋ฌธ์ ์ ๋ฐ์
- turn์ ๋ด ์ฐจ๋ก๋ก ๋ฐ๊ฟ์ค์ผ๋ง critical section์ ๋ค์ด๊ฐ ์ ์์
- ์๋๋ฐฉ์ด critical section์ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ฐจ๋ก๊ฐ ๋์์ค์ง ์์
- ์ํ๋ ์ํ์ง ์๋ ๋ฌด์กฐ๊ฑด ์ฐจ๋ก๊ฐ ์ค๋ฉด critical section์ ๋ค์ด๊ฐ๊ฒ ๋จ
Multual Exclusion์ ์ถฉ์กฑํ์์ง๋ง Progress๋ ์ถฉ์กฑํ์ง ๋ชปํจ
Algorithm 2
do {
flag[i] = true; /* Pretend I am in */
while (flag[j]); /* Is he also in? then wait */
critical section
flag[i] = false; /* I am out now */
remainder section
} while(1);
- Pi๊ฐ flag[i]๋ฅผ ๋ค์ด์ critical section์ ๋ค์ด๊ฐ๊ณ ์ถ๋ค๋ ์์ฌ๋ฅผ ํํ ํ Pj์ flag[j]์ ์ํ๋ฅผ ํ์ธํ๊ณ ๋ง์ฝ ๋๋ฌ์ผ๋ฉด flag[j] ๊น๋ฐ์ ๋ด๋ฆฌ๊ฒ ๋๊ณ flag[i]๊ฐ ๋ค์ด๊ฐ๊ฒ ๋จ
- ์๋ก ๊น๋ฐ๋ง ๋ค๊ณ ์๋ค๊ฐ CPU๋ฅผ ๋บ๊ฒจ ์๋ก ์๋ณดํ๋ ์ํฉ ๋ฐ์
- Progress ๋ฌธ์ ๋ฐ์
Multual Exclusion์ ์ถฉ์กฑํ์์ง๋ง Progress๋ ์ถฉ์กฑํ์ง ๋ชปํจ
Algorithm 3 (Petersonโs Algorithm)
do {
flag[i] = true; /* My intention is to enter ... */
turn = j; /* Set to his turn */
while (flag[i] && turn == j); /* wait only if ... */
critical section
flag[i] = false;
remainder section
} while(1);
- ๊น๋ฐ์ ํตํด์ ๋ค์ด๊ฐ๊ฒ ๋ค๋ ์์ฌ๋ฅผ ํํํ๊ณ ์๋๋ฐฉ์ด ๊น๋ฐ์ ๋ค๊ณ ์๋์ง ํ์ธ
- ๋์์ ๊น๋ฐ์ ๋ ์ํฉ์์๋ turn์ ์ด์ฉํด์ ์ ํด์ค
- Bysy Waiting (= spin lock)
- CPU์ memory๋ฅผ ์ฌ์ฉํ๋ฉด์ ๊ธฐ๋ค๋ฆฌ๋ ๋ฌธ์ ๋ฐ์ -> ๋นํจ์จ์
Synchroniztion Hardware
Semaphores
P ์ฐ์ฐ : ์์์ ํ๋ํ๋ ๊ณผ์ = lock ๊ณผ์ V ์ฐ์ฐ : ์์์ ๋ฐ๋ฉํ๋ ๊ณผ์ = unlock ๊ณผ์
Two Types of Semaphores
- Counting semaphore
- ๋๋ฉ์ธ์ด 0 ์ด์์ธ ์์์ ์ ์๊ฐ
- ์ฃผ๋ก resource counting์ ์ฌ์ฉ
- Binary semaphore (= mutex)
- 0 or 1 ๊ฐ๋ง ๊ฐ์ง ์ ์๋ semaphore
- ์ฃผ๋ก mutual exclusion (lock/unlock)์ ์ฌ์ฉ
Semaphores
- ์ผ์ข ์ ์ถ์ ์๋ฃํ
P(S) : ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ํ๋ํ๋ ๊ณผ์
V(S) : ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ฉํ๋ ๊ณผ์
Deadlock and Starvation
Deadlock
- ๋ ์ด์์ ํ๋ก์ธ์ค๊ฐ ์๋ก ์๋๋ฐฉ์ ์ํด ์ถฉ์กฑ๋ ์ ์๋ event๋ฅผ ๋ฌดํํ ๊ธฐ๋ค๋ฆฌ๋ ํ์
- P0์ ์ฅ์์๋ Q๋ฅผ ๋ชป์ป๊ณ P1์ ์ฅ์์๋ S๋ฅผ ๊ณ์ ๋ชป ์ป๋ ์ํฉ
- ํ๋ก์ธ์ค๋ค์ P์ฐ์ฐ์ผ๋ก ์์์ ํ๋ฒ์ ์ป๊ณ V์ฐ์ฐ์ผ๋ก ํ๋ฒ์ ๋ฐ๋ฉ์ ํจ
- P0์ P1์ S์ Q๋ฅผ ๋์์ ์ป์ด์ ๋์์ ๋ฐ๋ฉ
- S์ Q๊ฐ 1๋ก ์ด๊ธฐํ๋ semaphore
Starvation
- indefinite blocking ํ๋ก์ธ์ค๊ฐ suspend๋ ์ด์ ์ ํด๋นํ๋ ์ธ๋งํฌ์ด ํ์์ ๋น ์ ธ๋๊ฐ ์ ์๋ ํ์
Classical Problem of Synchronization
- Bounded-Buffer Problem (Producer-Consumer Problem)
- Readers and Writers Problem
- Dining-Philosophers Problem
Bounded-Buffer Problem (Producer-Consumer Problem)
Producer Process์๊ฒ๋ Empty ๋ฒํผ๊ฐ ์์, Consumer Process์๊ฒ๋ Full ๋ฒํผ๊ฐ ์์์ด๋ค.
Shared data(๊ณต์ ๋ฐ์ดํฐ)
- buffer ์์ฒด ๋ฐ buffer ์กฐ์ ๋ณ์(empty/full buffer์ ์์ ์์น)
- ๊ณต์ ๋ฐ์ดํฐ์๋ lock์ ๊ฑธ์ด์ ๋์ ์ ๊ทผ์ ๋ง์์ผํจ
Synchroniztion variables
- mutual exclusion -> Need binary semaphore(shared data์ mutual exclusion์ ์ํด)
- binary semaphore๋ฅผ ํตํด ์์์ lock/unlock ํจ
- resource count -> Need integer semaphore(๋จ์ full/empty buffer์ ์ ํ์)
- counting semaphore๋ฅผ ํตํด ์์์ ์๋ฅผ ์
Code
- semaphore full = 0, empty = n, mutex(lock/unlock์ ์ํ ๋ณ์) = 1
Readers-Writers Problem
- ํ process๊ฐ db์ write์ค์ผ ๋ ๋ค๋ฅธ process๊ฐ ์ ๊ทผํ๋ฉด ์ ๋จ
- read๋ ๋์์ ์ฌ๋ฟ์ด ์ ๊ทผํด๋ ๋จ
Solution
- writer๊ฐ db์ ์ ๊ทผ ํ๊ฐ๋ฅผ ์์ง ์ป์ง ๋ชปํ ์ํ์์๋ ๋ชจ๋ ๋๊ธฐ์ค์ธ reader๋ค์ ๋ค db์ ์ ๊ทผํ๊ฒ ํด์ค
- writer๋ ๋๊ธฐ ์ค์ธ reader๊ฐ ํ๋๋ ์์ ๋ db ์ ๊ทผ์ด ํ์ฉ๋๋ค
- ์ผ๋จ writer๊ฐ db์ ์ ๊ทผ์ค์ด๋ฉด reader๋ค์ ์ ๊ทผ์ด ๊ธ์ง๋๋ค.
- writer๊ฐ db์์ ๋น ์ ธ๋๊ฐ์ผ๋ง reader์ ์ ๊ทผ์ด ํ์ฉ๋๋ค.
Shared data
- DB ์์ฒด
- readcoun : ํ์ฌ DB์ ์ ๊ทผ ์ค์ธ Reader์ ์
Synchroniztion variables
- mutex : readcount๋ฅผ ์ ๊ทผํ๋ ์ฝ๋(critical section)์ mutual exclusion ๋ณด์ฅ์ ์ํด ์ฌ์ฉํ๋ค.
- db : reader์ writer๊ฐ ๊ณต์ db ์์ฒด๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ ๊ทผํ๊ฒ ํ๋ ์ญํ ์ ํ๋ค.
Code
- Shared data
- int readcount = 0;
- DB ์์ฒด;
- Synchronization variables
- semaphore mutex = 1, db= 1;
- writer๊ฐ ๋จผ์ ๋์ฐฉํ์ ์ง๋ผ๋ reader๊ฐ ๊ณ์ ๋ค์ด์จ๋ค๋ฉด starvation ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์
Dining-Philosophers Problem
์์ solution์ ๋ฌธ์ ์
- Deadlock ๊ฐ๋ฅ์ฑ์ด ์์
- ๋ชจ๋ ์ฒ ํ์๊ฐ ๋์์ ๋ฐฐ๊ฐ ๊ณ ํ์ ธ ์ผ์ชฝ ์ ๊ฐ๋ฝ์ ์ง์ด๋ฒ๋ฆฐ ๊ฒฝ์ฐ
ํด๊ฒฐ ๋ฐฉ์
- 4๋ช ์ ์ฒ ํ์๋ง์ด ํ ์ด๋ธ์ ๋์์ ์์ ์ ์๋๋ก ํจ
- ์ ๊ฐ๋ฝ์ ๋ ๊ฐ ๋ชจ๋ ์ง์ ์ ์์ ๋์๋ง ์ ๊ฐ๋ฝ์ ์ง์ ์ ์๊ฒ ํจ
- ๋น๋์นญ
- ์ง์(ํ์) ์ฒ ํ์๋ ์ผ์ชฝ(์ค๋ฅธ์ชฝ) ์ ๊ฐ๋ฝ๋ถํฐ ์ง๋๋กํจ
Code
Monitor
Semaphore์ ๋ฌธ์ ์
- ์ฝ๋ฉํ๊ธฐ ํ๋ฌ
- ์ ํ์ฑ(correctness)์ ์ ์ฆ์ด ์ด๋ ค์
- ์๋ฐ์ ํ๋ ฅ(voluntary cooperation)์ด ํ์
- ํ๋ฒ์ ์ค์๊ฐ ๋ชจ๋ ์์คํ ์ ์น๋ช ์ ์ํฅ
Monitor
- ๋์ ์ํ์ค์ธ ํ๋ก์ธ์ค ์ฌ์ด์์ abstract data type์ ์์ ํ ๊ณต์ ๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํ high-level synchronization construct