๋ณธ ๊ฒ์๊ธ์ KOCW ์ดํ์ฌ์๋ํ๊ต ๋ฐํจ๊ฒฝ ๊ต์๋์ <์ด์์ฒด์ > ๊ฐ์๋ฅผ ๋ฃ๊ณ ,
<ํผ์ ๊ณต๋ถํ๋ ์ปดํจํฐ๊ตฌ์กฐ + ์ด์์ฒด์ > ์ฑ ์ ์ฐธ๊ณ ํ์ฌ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
๊ฒ์๊ธ์ ํฌํจ๋๋ ์ด๋ฏธ์ง ์๋ฃ๋ <์ด์์ฒด์ > ๊ฐ์์ ํฌํจ๋ ๊ฐ์ ์๋ฃ์ ๋๋ค.
๋ฐ์ดํฐ ์ ๊ทผ ํจํด
ํ๋ก์ธ์ค ๋๊ธฐํ์ ๋ํด ์์๋ณด๊ธฐ์ ์์ ์ปดํจํฐ ์์คํ ๋ด์์ ๋ฐ์ดํฐ๊ฐ ์ ๊ทผ๋๋ ํจํด์ ๋ํด ๋จผ์ ์์๋ด ์๋ค.
๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋์ด์๋ ์์น์์ ์ฝ์ด์์ ์ฐ์ฐ์ ํ๊ณ ์์ ๋ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ๋ฐ์ดํฐ์ ๋ฐ์์ ํ๊ณ , ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋๋ Storage Box๋ ๊ณต์ ๋๊ธฐ ๋๋ฌธ์ ๋๊ธฐํ(synchronization) ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
๊ณต์ ๋ฐ์ดํฐ(shared data)์ ๋์ ์ ๊ทผ์ ๋ฐ์ดํฐ์ ๋ถ์ผ์น ๋ฌธ์ ๋ฅผ ๋ฐ์์ํฌ ์ ์์ต๋๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ(consistency) ์ ์ง๋ฅผ ์ํด์๋ ํ๋ ฅ ํ๋ก์ธ์ค ๊ฐ์ ์คํ ์์๋ฅผ ์ ํด์ฃผ๋ ๋ฉ์ปค๋์ฆ(= ํ๋ก์ธ์ค ๋๊ธฐํ)์ด ํ์ํฉ๋๋ค.
Race Condition
Race Condition์ด๋ ์ฌ๋ฌ ํ๋ก์ธ์ค๋ค์ด ๋์์ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ๋ ์ํฉ์ ์๋ฏธํฉ๋๋ค.
๋ ์ด์ค ์ปจ๋์ ์ด ๋ฐ์ํ๋ฉด ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ด ๊นจ์ง๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.(๋ฐ์ดํฐ์ ์ต์ข ์ฐ์ฐ ๊ฒฐ๊ณผ๋ ๋ง์ง๋ง์ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฌ ํ๋ก์ธ์ค๊ฐ ์ด๋ค ํ๋ก์ธ์ค๋์ ๋ฐ๋ผ ๋ฌ๋ผ์ง)
OS์์ Race Condition์ด ๋ฐ์ํ๋ ๊ฒฝ์ฐ
- ์ปค๋ ์ํ ์ค ์ธํฐ๋ฝํธ ๋ฐ์
- ํ๋ก์ธ์ค๊ฐ ์์คํ ์ฝ์ ํ์ฌ ์ปค๋ ๋ชจ๋๋ก ์ํ ์ค์ธ๋ฐ context switch๊ฐ ์ผ์ด๋๋ ๊ฒฝ์ฐ
- ๋ฉํฐํ๋ก์ธ์์์ shared memory ๋ด์ ์ปค๋ ๋ฐ์ดํฐ
Multiprocessor ํ๊ฒฝ์ด ์๋๋ผ๋ฉด, ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ ํ๋ก์ธ์ค๋ ์๊ธฐ ์ฃผ์ ๊ณต๊ฐ๋ง ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ race condition ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๊ฑฐ์ ์์ต๋๋ค. ํ์ง๋ง, ํ๋ก์ธ์ค๊ฐ ์ง์ ์คํํ ์ ์๋ ๋ถ๋ถ์ ์์คํ ์ฝ์ ํตํด ์ด์์ฒด์ ์ ์์ฒญํ๊ฒ ๋ฉ๋๋ค. ์ด ๋, ์ปค๋์ ์ฝ๋๊ฐ ์คํ๋๊ฒ ๋๋๋ฐ OS ์ปค๋ ์ฝ๋๋ ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ์คํํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ์๊ธฐ๊ฒ ๋ฉ๋๋ค. (์ปค๋์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ ๋์ค ๋ค๋ฅธ ์ธํฐ๋ฝํธ๊ฐ ๋ค์ด์ ๋ค๋ฅธ ๋ฃจํด์ ์ํํ๊ฒ ๋ ๊ฒฝ์ฐ race condition์ ๊ฐ๋ฅ์ฑ)
1. ์ปค๋ ์ํ ์ค ์ธํฐ๋ฝํธ ๋ฐ์
์์ ๊ทธ๋ฆผ์ ์ปค๋๋ชจ๋ running ์ค interrupt๊ฐ ๋ฐ์ํ์ฌ ์ธํฐ๋ฝํธ ์ฒ๋ฆฌ๋ฃจํด์ด ์ํ๋๋ ๊ฒฝ์ฐ์ ๋๋ค.
์์ชฝ ๋ค ์ปค๋ ์ฝ๋์ด๋ฏ๋ก ์ปค๋ ์ฃผ์ ๊ณต๊ฐ์ ๊ณต์ ํ๊ฒ ๋ฉ๋๋ค.
๊ณ ๊ธ ์ธ์ด๋ก ๋ ์ฝ๋ ํ์ค์ด ๋ณดํต CPU ๋ด๋ถ์์๋ ์ฌ๋ฌ๊ฐ์ instruction์ ํตํด ์คํ์ด ๋ฉ๋๋ค.
ex) count ๋ผ๋ ๋ฉ๋ชจ๋ฆฌ ๋ณ์๊ฐ์ 1 ์ฆ๊ฐ ์ํจ๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๋ณ์ ๊ฐ์ CPU ๋ ์ง์คํฐ๋ก ๋ถ๋ฌ๋ค์ธ๋ค.
- ๋ ์ง์คํฐ ๊ฐ 1์ฆ๊ฐ ์ํจ๋ค.
- ๋ ์ง์คํฐ์ ๊ฐ์ ๋ค์ ๋ฉ๋ชจ๋ฆฌ์ ๋ณ์ ์์น์ ์ด๋ค.
์์ ๊ทธ๋ฆผ์ ์์๋ก count ๊ฐ์ ๋ณํ๋ฅผ ์ดํด๋ด ์๋ค!
๋ง์ฝ ๋ ์ง์คํฐ๋ก ๋ถ๋ฌ๋ค์ธ ๋ค์, ๋ ์ง์คํฐ ๊ฐ์ 1 ์ฆ๊ฐ ์ํค๋ ์์ ์งํ ์ค์ ์ธํฐ๋ฝํธ๊ฐ ๋ฐ์ํ๋ค๋ฉด, ์ด ์์ ์ ์ ์ ๋ฉ์ถ๊ณ ์ธํฐ๋ฝํธ ์ฒ๋ฆฌ ๋ฃจํด์ผ๋ก ๋์ด๊ฐ๊ฒ ๋ฉ๋๋ค. ์ธํฐ๋ฝํธ ์ฒ๋ฆฌ(count--)๊ฐ ๋ค ๋๋ฉด ๋ค์ count++์ context๋ก ๋์์ค๊ฒ ๋๋๋ฐ, ์ด๋ count๊ฐ์ 1์ฆ๊ฐ, 1๊ฐ์ ์์ ์ ์ฐจ๋ก๋ก ์งํํ์ผ๋ ์๋์ ๊ฐ๊ณผ ๋์ผํด์ผ๊ฒ ์ฃ ? ํ์ง๋ง count--์ ์์ ์ ๋ฐ์์ด ๋์ง ์์ต๋๋ค. (๋ค์ ์๋ context๋ก ๋์์์ ๋ ์ด์ ์ ์ ์ฅํด๋์๋ ๊ฐ(1์ฆ๊ฐ์ํค๊ธฐ ์ ๊ฐ)์์ count++ ์ ์์ ์ ๋ง๋ฌด๋ฆฌํ๊ธฐ ๋๋ฌธ)
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ์ธํฐ๋ฝํธ๊ฐ ๋ค์ด์๋ ์ธํฐ๋ฝํธ ์ฒ๋ฆฌ๋ฃจํด์ผ๋ก ๋๊ธฐ์ง ์๊ณ ๋๊ธฐ ์ํจ๋ค์ ๋จผ์ ํ๋ ์ผ์ ๋ค ํ ํ์ ์ฒ๋ฆฌํ๋๋ก ์ธํฐ๋ฝํธ๋ฅผ ๋ง๋ ๋ฐฉ์์ผ๋ก ์์ ์ ์์๋ฅผ ์ ํด์ฃผ์ด์ผ ํฉ๋๋ค!
2. ํ๋ก์ธ์ค๊ฐ ์์คํ ์ฝ์ ํ์ฌ ์ปค๋ ๋ชจ๋๋ก ์ํ ์ค์ธ๋ฐ context switch๊ฐ ์ผ์ด๋๋ ๊ฒฝ์ฐ
์์ ๊ทธ๋ฆผ์์ ์์คํ ์ฝ์ ์ํด ์ ์ ๋ชจ๋์ ์ปค๋๋ชจ๋๊ฐ ๋ฒ๊ฐ์๊ฐ๋ฉฐ ์คํ๋๊ณ ์์ต๋๋ค. ๋ง์ฝ ์ฌ์ฉ์ ํ๋ก์ธ์ค๊ฐ ์์คํ ์ฝ์ ํ์ฌ ์ปค๋ ๋ชจ๋๋ก ํ๋ก์ธ์ค ์คํ์ค์ timer interrupt (CPU ํ ๋น์๊ฐ์ด ์๊ธฐ ๋๋ฌธ)๊ฐ ๊ฑธ๋ฆฌ๊ฒ ๋๋ฉด?
์์ ๊ทธ๋ฆผ์ฒ๋ผ CPU ์ ์ด๊ถ์ด ๋ค๋ฅธ ํ๋ก์ธ์ค์๊ฒ ๋์ด๊ฐ๊ฒ ๋ฉ๋๋ค. ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ count++ ์์ ์ ์ํํ์ง๋ง, CPU์ ์ด๊ถ์ด ๋ค์ PA์๊ฒ๋ก ๋์๊ฐ๊ฒ ๋๋ฉด PA๋ CPU ์ ์ด๊ถ์ ๋๊ฒจ์ค๋์ context์์ ์์ ์ ์ด์ด์ ํ๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ณผ์ ์ผ๋ก PA๊ฐ ์ํํ๋ count++ ๋ง ๋ฐ์๋๊ฒ ๋ฉ๋๋ค.
์ด๋ฐ ๊ฒฝ์ฐ๋ ํ๋ก์ธ์ค๊ฐ ์ปค๋๋ชจ๋์ ์๋ค๋ฉด CPU ํ ๋น์๊ฐ์ด ๋๋๋๋ผ๋ CPU๋ฅผ preempt ํ์ง ๋ชปํ๊ฒ ํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. (์ปค๋๋ชจ๋์์ ์ ์ ๋ชจ๋๋ก ๋น ์ ธ๋์ฌ๋ CPU๋ฅผ ๋นผ์๊ธฐ)
3. ๋ฉํฐํ๋ก์ธ์์์ shared memory ๋ด์ ์ปค๋ ๋ฐ์ดํฐ
CPU๊ฐ ์ฌ๋ฌ๊ฐ์ธ ๋ฉํฐํ๋ก์ธ์ ํ๊ฒฝ์ ๊ฒฝ์ฐ ์์์์ ํด๊ฒฐ๋ฐฉ๋ฒ์ด์๋ ์ธํฐ๋ฝํธ๋ฅผ ๋ง๋ ๋ฐฉ๋ฒ์ผ๋ก๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค.
๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ:
1. ์ปค๋์ ์ ๊ทผํ๋ CPU๊ฐ ๋งค์๊ฐ ํ๋๋ง ์๋๋ก ์ปค๋ ์ ์ฒด๋ฅผ lock์ผ๋ก ๋ง๊ณ ๋น ์ ธ๋์ฌ ๋ lock์ ํ์ด์ฃผ๋ ๋ฐฉ๋ฒ (๋นํจ์จ์ )
2. ๊ณต์ ๋ฐ์ดํฐ์ ์ ๊ทผํ ๋ ๊ทธ ๋ฐ์ดํฐ์ ๋ํ lock / unlock ์ ๊ฑธ์ด์ ํ๋ก์ธ์์ ์ ๊ทผ์ ์ ์ดํ๋ ๋ฐฉ๋ฒ (ํจ์จ์ )
Critical Section (์๊ณ๊ตฌ์ญ)
Critical Section: ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ๋ ์ฝ๋
๊ฐ ํ๋ก์ธ์ค์ code segment์๋ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ๋ ์ฝ๋์ธ critical section์ด ์กด์ฌํฉ๋๋ค.
n๊ฐ์ ํ๋ก์ธ์ค๊ฐ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ๋์์ ์ฌ์ฉํ๊ธฐ๋ฅผ ์ํ๋ ๊ฒฝ์ฐ, ํ๋์ ํ๋ก์ธ์ค๊ฐ critical section์ ์์ ๋ ๋ค๋ฅธ ๋ชจ๋ ํ๋ก์ธ์ค๋ critical section์ ๋ค์ด๊ฐ ์ ์์ด์ผ ํฉ๋๋ค.
ํด๊ฒฐ์ฑ 1: Lock (๋ฎคํ ์ค ๋ฝ)
๊ฐ์
- ๋ ๊ฐ์ ํ๋ก์ธ์ค๊ฐ ์๋ค๊ณ ๊ฐ์ (P0, P1)
- ํ๋ก์ธ์ค๋ค์ ์ผ๋ฐ์ ์ธ ๊ตฌ์กฐ
do {
entry section // lock
critical section
exit section // unlock
remainder section
} while(1);
- ํ๋ก์ธ์ค๋ค์ ์ํ์ ๋๊ธฐํ(synchronize)๋ฅผ ์ํด ๋ช๋ช ๋ณ์(synchronization variable)๋ฅผ ๊ณต์ ํ ์ ์๋ค.
ํ๋ก๊ทธ๋จ์ ํด๊ฒฐ๋ฒ์ ์ถฉ์กฑ์กฐ๊ฑด
- Mutual Exclusion(์ํธ๋ฐฐ์ ): ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๋์์ ์๊ณ ๊ตฌ์ญ์ ๋ค์ด๊ฐ๋ ๊ฒ์ ๋ง์(์๊ณ๊ตฌ์ญ์๋ ํ๋์ ํ๋ก์ธ์ค๋ง)
- Progress(์งํ): ์๋ฌด๋ ์๊ณ๊ตฌ์ญ์ ์๋ ์ํ์์ ๋ค์ด๊ฐ๊ณ ์ ํ๋ ํ๋ก์ธ์ค๊ฐ ์์ผ๋ฉด ๋ค์ด๊ฐ๊ฒ ํด์ฃผ์ด์ผ ํจ
- Bounded Waiting(์ ํ ๋๊ธฐ): ํ๋ก์ธ์ค๊ฐ critical section ์ ๋ค์ด๊ฐ๋ ค๊ณ ์์ฒญํ ํ๋ถํฐ ์์ฒญ์ด ํ์ฉ๋๊ธฐ ์ ๊น์ง ๋ค๋ฅธ ํ๋ก์ธ์ค๋ค์ด critical section ์ ๋ค์ด๊ฐ๋ ํ์์ ํ๊ณ๊ฐ ์์ด์ผ ํจ(์ด๋ค ํ๋ก์ธ์ค๊ฐ ๋ฌดํํ ๋๊ธฐํ๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ก)
Algorithm 1
- synchronization variable: turn
int turn = 0;
// turn ์ด i ์ด๋ฉด Pi ๊ฐ critical section ์ ๋ค์ด๊ฐ ์ ์์
- Process P0
do {
while (turn != 0); // turn ์ด 0 ์ด ์๋๋ฉด turn ์ฒดํฌํ๋ฉฐ ๋ฌดํ๋ฃจํ ๋๊ธฐ
critical section
turn = 1; // critical section ๋์ฌ ๋ ์๋๋ฐฉ์ ์ฐจ๋ก๋ก ๋๊ฒจ์ค
remainder section
} while(1);
- mutual exclusion ์กฐ๊ฑด ์ถฉ์กฑO / but progress ์กฐ๊ฑด ์ถฉ์กฑX
- ๋์ ์ ๊ทผ์ ์ผ์ด๋์ง ์์ง๋ง ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ๋ค ๋์์ผ๋ง ์ฐจ๋ก๊ฐ ๋์์ด
Algorithm 2
- synchronization variable: flag
boolean flag[2] = { false }; // flag [i] == true ์ด๋ฉด Pi ๊ฐ critical section ์ ์ ๊ทผํ ์ค๋น์๋ฃ๋ ๊ฒ
- Process P0
do {
flag[i] = true; // ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ๊ณ ์ ํ๋ ์์ฌ ํ์
while (flag[j]); // ์๋๋ฐฉ์ flag ์ฒดํฌ (์๋๋ฐฉ์ด ์๊ณ๊ตฌ์ญ์ ์๋ค๋ฉด(=true) ๋๊ธฐ)
critical section
flag[i] = false; // ๋์ฌ ๋ false๋ก ๋ฐ๊ฟ์ค(unlock)
remainder section
} while(1);
- mutual exclusion ์กฐ๊ฑด ์ถฉ์กฑO / but progress ์กฐ๊ฑด ์ถฉ์กฑX
- ๋ง์ฝ ์๊ณ๊ตฌ์ญ ๋ค์ด๊ฐ๋ ค๊ณ flag๋ฅผ true๋ก ๋ฐ๊พผ ์ํ์์ CPU ๋นผ์๊ธด๋ค๋ฉด ์๊ณ๊ตฌ์ญ์ ์๋ฌด๋ ์๋๋ฐ true ์ํ์ธ ๊ฒ
- ๋ค๋ฅธ ํ๋ก์ธ์ค๋ ์๊ณ๊ตฌ์ญ์ ๋๊ฐ ์๋ค๊ณ ํ๋จํด์ ๊ณ์ ๊ธฐ๋ค๋ฆฌ๋ ์ํฉ์ด ์๊น -> ์๋ฌด๋ ๋ค์ด๊ฐ ์ ์๋ ์ํฉ์ด ์๊ธธ ์ ์์
Algorithm 3 (Peterson's Algorithm)
- synchronization variable: turn, flag ๋๋ค ์ฌ์ฉ
do {
flag[i] = true; // enter ์์ฌ ํํ (flag true๋ก ๋ณ๊ฒฝ)
turn = j; // ์๊ณ๊ตฌ์ญ ๋ค์ด๊ฐ๊ธฐ ์ ์ turn ๋ณ์ ๋ณ๊ฒฝ (turn ์๋๋ฐฉ์ผ๋ก ์ธํ
)
while (flag[j] && turn == j); // ์๋๋ฐฉ์ flag, turn ์ฒดํฌ (turn์ด ์๋๋ฐฉ && flag๋ true์ด๋ฉด ๊ธฐ๋ค๋ฆผ)
critical section
flag[i] = false; // ๋์ฌ ๋ unlock
remainder section
} while(1);
- ๋ณ์๋ฅผ ๋๊ฐ ๋ชจ๋ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ค๊ฐ ์ด๋์์ CPU๋ฅผ ๋นผ์๊ธด๋ค ํ๋๋ผ๋ ๋ชจ๋ ์กฐ๊ฑด ์ถฉ์กฑํ๋ ์๊ณ ๋ฆฌ์ฆ
- ํ์ง๋ง Busy Waiting(= spin lock) ์ด๋ผ๋ ๋ฌธ์ ๊ฐ ์์ - ๊ณ์ CPU ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐ๋ฉด์ ๊ธฐ๋ค๋ฆฌ๊ฒ ๋จ(๋นํจ์จ์ )
- ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ critical section ์ ๋ค์ด๊ฐ์์ผ๋ฉด ๋ณธ์ธ์ CPU ํ ๋น์๊ฐ ๋์ ๊ณ์ while ๋ฌธ์ ๋๋ฉด์ critical section ์ ๋ค์ด๊ฐ ์ ์๋์ง ์ฒดํฌํจ. but ์๋๋ฐฉ์ด CPU๋ฅผ ์ก๊ธฐ ์ ์๋ ์ฒดํฌํ๋ ๊ฐ์ด ๋ฐ๋์ง ์์
Synchronization Hardware
ํ๋ก์ธ์ค ๋๊ธฐํ ๋ฌธ์ ๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ฐ๋ ๊ฒ์ด ํ๋์ instruction ์ผ๋ก ์ด๋ฃจ์ด์ ธ์์ง ์์์ ๋ฐ์ํ๋ ๋ฌธ์ ์ ๋๋ค.
ํ๋์จ์ด์ ์ผ๋ก Test & modify๋ฅผ atomicํ๊ฒ(๋์์) ์ํํ ์ ์๋๋ก ์ง์ํ๋ค๋ฉด ์ด๋ฌํ ๋ฌธ์ ๋ ๊ฐ๋จํ ํด๊ฒฐํ ์ ์์ต๋๋ค.
- synchronization variable: lock
boolean lock = false;
do {
while (Test_and-Set(lock)); // ์๋ ๊ฐ ์ฝ์ด๋ด๊ณ (lock ์ฒดํฌ) ๊ทธ ์๋ฆฌ์ true๋ก ์ธํ
critical section
lock = false; // ๋์ฌ ๋ unlock
remainder section
} while(1);
ํด๊ฒฐ์ฑ 2: Semaphore(์ธ๋งํฌ์ด)
์ธ๋งํฌ์ด๋ ์ผ์ข ์ ์ถ์์๋ฃํ(๋ ผ๋ฆฌ์ ์ผ๋ก ์ ์ํ๋ ๊ฒ. ์ค์ ์ปดํจํฐ์์ ๊ตฌํ๋๋ ๊ฒ๊ณผ ๋ณ๊ฐ)์ ๋๋ค.
ํ๋ก๊ทธ๋๋จธ๊ฐ critical section ์ ๋ค์ด๊ฐ๋ ๋ชจ๋ ์ฝ๋๋ฅผ ์ ๊ฒฝ์ฐ๊ธด ํ๋๋ ์ถ์์๋ฃํ(ํ๋กํผํฐ์ ๋ฉ์๋๋ก ์ด๋ฃจ์ด์ง ๋ ผ๋ฆฌ์๋ฃํ)์ผ๋ก ์ฐ์ฐ์ ํตํด ํ์ธํ ์ ์๊ฒ ๋ง๋๋ ๊ฒ์ ๋๋ค.
์ธ๋งํฌ์ด๋ ๊ณต์ ์์์ด ์ฌ๋ฌ ๊ฐ ์๋ ์ํฉ์์๋ ์ ์ฉ์ด ๊ฐ๋ฅํ ๋๊ธฐํ ๋๊ตฌ์ ๋๋ค. (cf. ๋ฎคํ ์ค ๋ฝ์ ํ๋์ ๊ณต์ ์์ ๋์)
์ธ๋งํฌ์ด์ ์ข ๋ฅ
1. counting semaphore
- ์์์ ๊ฐ์๊ฐ ์ฌ๋ฌ ๊ฐ -> 0 ์ด์์ ์ ์๊ฐ์ ์ฌ์ฉ
2. binary semaphore (= mutex lock)
- 0 ๋๋ 1์ ๊ฐ๋ง ๊ฐ์ง
- mutual exclusion (lock / unlock) ์ ์ฌ์ฉํ๋ค. (= ๋ฎคํ ์ค ๋ฝ)
Semaphore S
- integer ๋ณ์
- ์๋์ ๋ ๊ฐ์ง atomic ์ฐ์ฐ(P, V)์ ์ํด์๋ง ์ ๊ทผ ๊ฐ๋ฅ
P(S): while (S <= 0) do no-op
S--;
V(S): S++;
- P ์ฐ์ฐ
- S๊ฐ์ด 0์ดํ(=์ธ ์ ์๋์์์ด ์์)์ธ ๋์ while๋ฌธ ๋๋ฉด์ wait
- S๊ฐ์ด ์์๊ฐ ๋๋ฉด(= ๋๊ตฐ๊ฐ๊ฐ ์์์ ๋ด์ด๋์ผ๋ฉด) ๊ทธ ๋ S--, ์์ ํ๋, lock
- V ์ฐ์ฐ
- ๊ณต์ ์์ ๋ฐ๋ฉ, S++, unlock
// Synchronization variable
Semaphore mutex;
// Process Pi
do {
P(mutex);
critical section
V(mutex);
remainder section
} while(1);
์ธ๋งํฌ์ด๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ์ธ๋งํฌ์ด ๋ณ์์ธ mutex๋ฅผ 1๋ก ๋๊ณ lock์ ๊ฑธ๋(= ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ ๋) P์ฐ์ฐ, ํ ๋(์๊ณ๊ตฌ์ญ์์ ๋น ์ ธ๋์ฌ๋) V์ฐ์ฐ์ ํด์ฃผ๋ฉด ์๊ณ๊ตฌ์ญ ๋ฌธ์ ๊ฐ ์์ฐ์ค๋ฝ๊ฒ ํด๊ฒฐ๋ฉ๋๋ค. ํ์ง๋ง busy-waiting (= spin lock)๋ฌธ์ ๋ ์ฌ์ ํ ๋ฐ์ํ๋๋ฐ, ์ด๋ ํจ์จ์ ์ด์ง ๋ชปํ๋ฏ๋ก Block & Wakeup (= sleep lock) ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ ์์ต๋๋ค.
Block & Wakeup Implementation
์ธ๋งํฌ์ด ์ ์
- S: ์ธ๋งํฌ์ด ๋ณ์
- L: ํ๋ก์ธ์ค ๋๊ธฐ ํ
- block: ์ปค๋์ block์ ํธ์ถํ ํ๋ก์ธ์ค๋ฅผ suspend ์ํด. ์ด ํ๋ก์ธ์ค์ PCB๋ฅผ ์ธ๋งํฌ์ด์ ๋ํ wait queue์ ๋ฃ์
- wakeup(P): block๋ ํ๋ก์ธ์ค P๋ฅผ wakeup ์ํด. ์ด ํ๋ก์ธ์ค์ PCB๋ฅผ ready queue๋ก ์ฎ๊น
์ฐ์ฐ
P(S)
S.value--;
if (S.value < 0) { // ๊ณต์ ์์ ์ ๊ทผ ๋ถ๊ฐ
add this process to S.L;
block(); // suspend
}
V(S)
S.value++;
if (S.value <= 0) { // ์์์ ๋ด๋จ๋๋ฐ ๊ธฐ๋ค๋ฆฌ๋ ํ๋ก์ธ์ค๊ฐ ์์
remove a process P from S.L;
wakeup(P); // wakeup
}
ํ๋ก์ธ์ค ์์ฒด๋ฅผ blocked ์์ผ์ ํด๋น ํ๋ก์ธ์ค๊ฐ CPU๋ฅผ ์์ ๋ฐ๋ฉํ๊ณ ์ ๋ค์ด ์๋ค๊ฐ ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ ํ๋ก์ธ์ค๊ฐ CPU๋ฅผ ๋ด๋์ผ๋ฉด ๊ทธ ๋ ready queue์ ๋ค์ด๊ฐ์ CPU๋ฅผ ์ป๋ ๋ฐฉ์(์ธ๋ฐ์์ด CPU๋ฅผ ์ก๊ณ ์์ผ๋ฉด์ ๊ธฐ๋ค๋ฆฌ์ง ์์)์ ๋๋ค.
block & wakeup ๋ฐฉ์์ ๊ฒฝ์ฐ, ํ๋ก์ธ์ค๋ฅผ ์ฌ์ฐ๊ณ ๊นจ์ฐ๋๋ฐ์ ๋ํ ์ค๋ฒํค๋๊ฐ ์์ผ๋ฏ๋ก critical section ์ ๊ธธ์ด๊ฐ ๋งค์ฐ ์งง์ ๊ฒฝ์ฐ busy-wait ๊ฐ ๋์ ์๋ ์์ง๋ง ์ผ๋ฐ์ ์ผ๋ก๋ block & wakeup ์ด ๋ ํจ์จ์ (CPU ์ด์ฉ๋ฅ ์ธก๋ฉด์์)์ ๋๋ค.
์ธ๋งํฌ์ด์ ๋ฌธ์ ์ : Deadlock & Starvation
๋ง์ฝ ํ๋ก์ธ์ค๊ฐ S, Q์์ ๋ชจ๋ ์ฌ์ฉํด์ผํ๋ค๋ฉด,
๋ ๊ฐ์ ํ๋ก์ธ์ค๊ฐ ์๋ก์ ์ํด ์์ํ S, Q ์์ ๋ ๊ฐ ๋ชจ๋๋ฅผ ํ๊บผ๋ฒ์ ํ๋ํ ์ ์๋ ๋ฌธ์ ๊ฐ ์๊ธฐ๊ฒ ๋ฉ๋๋ค. (Deadlock)
ํ๋ก์ธ์ค๊ฐ ํ๋์ ์์์ ์ ์ ํ ์ฑ๋ก ๋ค๋ฅธ ์์์ ์ป๊ธฐ ์ํด ๊ธฐ๋ค๋ฆฌ๊ฒ ๋๋๋ฐ, ํ๋์ฉ ์ ์ ํ ์ํ๋ผ๋ฉด ํ๋ํ ์ ์๋ ์์์ ๋ฌดํํ ๊ธฐ๋ค๋ฆฌ๊ฒ ๋๋ ๊ฒ์ ๋๋ค. (Starvation)
- Deadlock: ๋ ์ด์์ ํ๋ก์ธ์ค๊ฐ ์๋ก ์๋๋ฐฉ์ ์ํด ์ถฉ์กฑ๋ ์ ์๋ event๋ฅผ ๋ฌดํํ ๊ธฐ๋ค๋ฆฌ๋ ํ์
- Starvation: ํ๋ก์ธ์ค๊ฐ suspend๋ ์ด์ ์ ํด๋นํ๋ ์ธ๋งํฌ์ด ํ์์ ๋น ์ ธ๋๊ฐ ์ ์๋ ํ์. ์ผ๋ถ ํ๋ก์ธ์ค์ ๊ณต์ ์์์ ๋ ์ ์ผ๋ก ์ด๋ค ํ๋ก์ธ์ค๋ ์์ํ ์์์ ์ป์ง ๋ชปํด์ ์คํ๋์ง ๋ชปํจ. (indefinite blocking)
- Deadlock๋ Starvation์ ์ผ์ข ์ผ๋ก ๋ณผ ์ ์์
'๐ฅ CS > ์ด์์ฒด์ ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์ด์์ฒด์ ] ๊ต์ฐฉ ์ํ (Deadlock) (2) | 2023.06.09 |
---|---|
[์ด์์ฒด์ ] ํ๋ก์ธ์ค ๋๊ธฐํ (2/2) (0) | 2023.06.08 |
[์ด์์ฒด์ ] CPU ์ค์ผ์ค๋ง (0) | 2023.03.09 |
[์ด์์ฒด์ ] ์ค๋ ๋ (Thread) (0) | 2023.02.24 |
[์ด์์ฒด์ ] ํ๋ก์ธ์ค ๊ด๋ฆฌ (0) | 2023.02.16 |