์ด์์ฒด์ ๊ณต๋ฃก์ฑ : Ch6. Synchronization Tools | ๋๊ธฐํ ๋๊ตฌ๋ค
๐ ๋ค์ด๊ฐ๋ฉฐ
ํ๋ ฅ์ ํ๋ก์ธ์ค cooperating process๋ ์์คํ ๋ด์์ ์คํ ์ค์ธ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์คํ์ ์ํฅ์ ์ฃผ๊ฑฐ๋ ์ํฅ์ ๋ฐ๋ ํ๋ก์ธ์ค์ด๋ค. ํ๋ ฅ์ ํ๋ก์ธ์ค๋ ๋ ผ๋ฆฌ ์ฃผ์ ๊ณต๊ฐ(์ฆ, ์ฝ๋ ๋ฐ ๋ฐ์ดํฐ)์ ์ง์ ๊ณต์ ํ๊ฑฐ๋ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๋๋ ๋ฉ์์ง ์ ๋ฌ์ ํตํด์๋ง ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์๋๋ฐ, ๊ณต์ ๋ฐ์ดํฐ๋ฅผ ๋์์ ์ ๊ทผํ๋ฉด ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ๋ง์น ์ ์๋ค. ์ด๋ฒ ๋จ์์์๋ ๋ ผ๋ฆฌ ์ฃผ์ ๊ณต๊ฐ์ ๊ณต์ ํ๋ ํ๋ ฅ์ ํ๋ก์ธ์ค๊ฐ ์ง์์๋ ์คํ์ ํตํด ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ ๋ค์ํ ๋ฉ์ปค๋์ฆ์ ๋ํด ๋ค๋ฃจ์ด๋ณด์.
๐ 6.1 ๋ฐฐ๊ฒฝ Background
ํ๋ก์ธ์ค๋ concurrentํ๊ณ parallelํ๊ฒ ์คํ๋ ์ ์๋ค. ์ฆ, CPU ์ค์ผ์ค๋ฌ๊ฐ ํ๋ก์ธ์ค ์ฌ์ด์์ ๋น ๋ฅด๊ฒ ์ค๊ฐ๋ฉฐ ๊ฐ ํ๋ก์ธ์ค๋ฅผ ์คํํ๋ฉฐ ๊ฐ ํ๋ก์ธ์ค๋ฅผ ์คํํ์ฌ ๋ชจ๋ ํ๋ก์ธ์ค๋ฅผ ๋ณํ ์คํ์ํจ๋ค.
์ด๊ฒ์ด ์๋ฏธํ๋ ๋ฐ๋, ํ ํ๋ก์ธ์ค๋ ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ์ค์ผ์ค ๋๊ธฐ ์ ์ ์ผ๋ถ๋ถ๋ง ์งํํ ์ ์๋ค๋ ๊ฒ์ด๋ค. ์ฌ์ค ํ๋ก์ธ์ค๋ ๋ช ๋ น์ด๊ฐ ์คํ๋ ๋ ์ด๋ ์ง์ ์์๋ ์ธํฐ๋ฝํธ ๋ ์ ์๊ณ , ์ฒ๋ฆฌ ์ฝ์ด๋ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๋ช ๋ น์ด๋ฅผ ์คํํ๋๋ก ํ ๋น๋ ์ ์๋ค. ๋ํ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ์ํ ๋ ๊ฐ์ ๋ช ๋ น์ด ํ๋ฆ์ด ๋์์ ๋ค๋ฅธ ์ฒ๋ฆฌ ์ฝ์ด์์ ์คํ๋ ์๋ ์๋ค. ์ด ๊ณผ์ ์์์ ๋์ ํน์ ๋ณ๋ ฌ ์คํ์ด ์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ๊ณต์ ํ๋ ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ ์ด๋ค ์ํฅ์ ์ฃผ๊ฒ ๋ ๊น?
๋์์ ์ฌ๋ฌ ๊ฐ์ ํ๋ก์ธ์ค๊ฐ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ์ ๊ทผํ์ฌ ์กฐ์ํ๊ณ , ๊ทธ ์คํ ๊ฒฐ๊ณผ๊ฐ ์ ๊ทผ์ด ๋ฐ์ํ ํน์ ์์์ ์์กดํ๋ ์ํฉ์ ๊ฒฝ์ ์ํฉ race condition์ด๋ผ๊ณ ํ๋ค. ๊ฒฝ์ ์ํฉ์ผ๋ก๋ถํฐ ๋ณดํธํ๊ธฐ ์ํด, ํ์๊ฐ์ ํ๋์ ํ๋ก์ธ์ค๋ง์ด ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๋๋ก ๋ณด์ฅํด์ผ ํ๋ค. ์ด๋ฌํ ๋ณด์ฅ์ ์ํด, ์ด๋ค ํํ๋ก๋ ํ๋ก์ธ์ค๋ค์ด ๋๊ธฐํ๋์ด์ผ ํ๋ค.
๐ 6.2 ์๊ณ๊ตฌ์ญ ๋ฌธ์ The Critical-Section Problem
n๊ฐ์ ํ๋ก์ธ์ค๋ก ์ด๋ฃจ์ด์ง ์์คํ ์ด ์๋ค๊ณ ํ ๋, ๊ฐ ํ๋ก์ธ์ค๋ ์๊ณ๊ตฌ์ญ critical section์ด๋ผ๊ณ ๋ถ๋ฅด๋ ์ฝ๋ ๋ถ๋ถ์ ํฌํจํ๊ณ ์๊ณ , ๊ทธ ์์์๋ ์ ์ด๋ ํ๋ ์ด์์ ๋ค๋ฅธ ํ๋ก์ธ์ค์ ๊ณต์ ํ๋ ๋ฐ์ดํฐ์ ์ ๊ทผํ๊ณ ๊ฐฑ์ ํ ์ ์๋ค. ํ ํ๋ก์ธ์ค๊ฐ ์์ ์ ์๊ณ๊ตฌ์ญ์์ ์ํํ๋ ๋์์๋ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ค์ ๊ทธ๋ค์ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ ์ ์๋ค๋ ์ ์ด ์ค์ํ๋ค. ์ฝ๊ฒ ๋งํด ๋ ํ๋ก์ธ์ค๋ ๋์์ ๊ทธ๋ค์ ์๊ณ๊ตฌ์ญ์ ์คํํ ์ ์๋ค.
์๊ณ๊ตฌ์ญ ๋ฌธ์ ๋ ํ๋ก์ธ์ค๋ค์ด ๋ฐ์ดํฐ๋ฅผ ํ๋ ฅ์ ์ผ๋ก ๊ณต์ ํ๊ธฐ ์ํด ์์ ๋ค์ ํ๋์ ๋๊ธฐํํ ๋ ์ฌ์ฉํ ์ ์๋ ํ๋กํ ์ฝ์ ์ค๊ณํ๋ ๊ฒ์ด๋ค. ๊ฐ ํ๋ก์ธ์ค๋ ์์ ์ ์๊ณ๊ตฌ์ญ์ผ๋ก ์ง์ ํ๋ ค๋ฉด ์ง์ ํ๊ฐ๋ฅผ ์์ฒญํด์ผ ํ๋๋ฐ, ์ด๋ฌํ ์์ฒญ์ ๊ตฌํํ๋ ์ฝ๋ ๋ถ๋ถ์ ์ง์ ๊ตฌ์ญ entry section์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค. ์๊ณ๊ตฌ์ญ ๋ค์๋ ํด์ถ ๊ตฌ์ญ exit section์ด ๋ฐ๋ผ์ฌ ์ ์๋ค. ์ฝ๋์ ๋๋จธ์ง ๋ถ๋ถ๋ค์ ์ด์นญํ์ฌ ๋๋จธ์ง ๊ตฌ์ญ remainder section์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์๊ณ๊ตฌ์ญ ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ์์ ๋ค์์ ์ธ๊ฐ์ง ์๊ตฌ ์กฐ๊ฑด์ ์ถฉ์กฑํด์ผ ํ๋ค.
- ์ํธ ๋ฐฐ์ mutual exclusion
- ๋ง์ฝ ํ๋ก์ธ์ค P_i๊ฐ ์์ ์ ์๊ณ๊ตฌ์ญ์์ ์คํ๋๋ค๋ฉด, ๋ค๋ฅธ ํ๋ก์ธ์ค๋ค์ ๊ทธ๋ค ์์ ์ ์๊ณ๊ตฌ์ญ์์ ์คํ๋ ์ ์๋ค.
- ์งํ progress
- ๋ง์ฝ ์๋ฌด ํ๋ก์ธ์ค๋ ์์ ์ ์๊ณ๊ตฌ์ญ์ ์คํํ๊ณ ์์ง ์๊ณ , ์ด๋ค ํ๋ก์ธ์ค๋ค์ด ์์ ์ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ๋ ค๊ณ ํ๋ค๋ฉด, ๋๋จธ์ง ๊ตฌ์ญ์์ ์คํ ์ค์ด์ง ์์ ํ๋ก์ธ์ค๋ค๋ง ๋ค์์ ๋๊ฐ ์๊ณ๊ตฌ์ญ์ผ๋ก ์ง์ ํ ์ ์๋์ง๋ฅผ ๊ฒฐ์ ํ๋ฉฐ, ์ด ์ ํ์ ๋ฌดํ์ ๋ฏธ๋ค์ง ์ ์๋ค.
- ํ์ ๋ ๋๊ธฐ bounded waiting
- ํ๋ก์ธ์ค๊ฐ ์๊ธฐ์ ์๊ณ๊ตฌ์ญ์ ์ง์ ํ๋ ค๋ ์์ฒญ์ ํ ํ๋ถํฐ ๊ทธ ์์ฒญ์ด ํ์ฉ๋ ๋๊น์ง ๋ค๋ฅธ ํ๋ก์ธ์ค๋ค์ด ๊ทธ๋ค ์์ ์ ์๊ณ๊ตฌ์ญ์ ์ง์ ํ๋๋ก ํ์ฉ๋๋ ํ์์ ํ๊ณ๊ฐ ์์ด์ผ ํ๋ค.
์ด์์ฒด์ ๋ด์์ ์๊ณ๊ตฌ์ญ์ ๋ค๋ฃจ๊ธฐ ์ํด ์ ์ ํ ์ปค๋ preemptive kernel๊ณผ ๋น์ ์ ํ ์ปค๋ nonpreemptive kernel์ ๋ ๊ฐ์ง ์ผ๋ฐ์ ์ธ ์ ๊ทผ๋ฒ์ด ์ฌ์ฉ๋๋ค. ์ ์ ํ ์ปค๋์ ํ๋ก์ธ์ค๊ฐ ์ปค๋ ๋ชจ๋์์ ์ํ๋๋ ๋์ ์ ์ ๋๋ ๊ฒ์ ํ์ฉํ๋ค. ๋น์ ์ ํ ์ปค๋์ ์ปค๋ ๋ชจ๋์์ ์ํ๋๋ ํ๋ก์ธ์ค์ ์ ์ ์ ํ์ฉํ์ง ์๊ณ ์ปค๋ ๋ชจ๋ ํ๋ก์ธ์ค๋ ์ปค๋์ ๋น ์ ธ๋๊ฐ ๋๊น์ง ๋๋ block ๋ ๋๊น์ง ๋๋ ์๋ฐ์ ์ผ๋ก CPU์ ์ ์ด๋ฅผ ์๋ณดํ ๋๊น์ง ๊ณ์ ์ํ๋๋ค.
๋น์ ์ ํ ์ปค๋์ ์ปค๋ ์์์ ์คํ ์ค์ธ ํ๋ก์ธ์ค๋ ํ๋ ๋ฐ์ ์์ผ๋ฏ๋ก ์ปค๋ ์๋ฃ๊ตฌ์กฐ์ ๋ํ ๊ฒฝ์ ์กฐ๊ฑด์ ์ผ๋ คํ ํ์๊ฐ ์๋ค. ๊ทธ์ ๋นํด ์ ์ ํ ์ปค๋์ ๊ฒฝ์ ์กฐ๊ฑด์ด ๋ฐ์ํ์ง ์๋๋ก ์ ์คํ๊ฒ ์ค๊ณํด์ผ ํ๋ค. ๊ทธ๋ฐ๋ฐ๋ ์ ์ ์ ์ ์ปค๋์ ๋ ์ฌ์ฉํ๋ ๊ฒ์ผ๊น? ์ ์ ํ ์ปค๋์ ๊ฒฝ์ฐ, ์ปค๋ ๋ชจ๋ ํ๋ก์ธ์ค๊ฐ ๋๊ธฐ ํ๋ก์ธ์ค๋ก ๋๊ธฐ๊น์ง ์๋นํ ๊ธด ๊ธฐ๊ฐ ๋์ ์คํ๋ ์ํ์ด ์ ๊ธฐ์ ์๋ต์ด ๋ฏผ์ฒฉํด์ง ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์ ํ ์ปค๋์ ์ค์๊ฐ ํ๋ก์ธ์ค๊ฐ ํ์ฌ ์ปค๋์์ ์คํ ์ค์ธ ํ๋ก์ธ์ค๋ฅผ ์ ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ์ค์๊ฐ ํ๋ก๊ทธ๋๋ฐ์ ๋ ์ ํฉํ๋ค.
๐ 6.3 ํผํฐ์จ์ ํด๊ฒฐ์ Peterson's Solution
์๊ณ๊ตฌ์ญ์ ๋ํ ๊ณ ์ ์ ์ธ ์ํํธ์จ์ด ๊ธฐ๋ฐ ํด๊ฒฐ์ฑ ์ธ ํผํฐ์จ์ ํด๊ฒฐ์์ ๋ํด ์์๋ณด์.
ํผํฐ์จ์ ํด๊ฒฐ์์ ์๊ณ๊ตฌ์ญ๊ณผ ๋๋จธ์ง ๊ตฌ์ญ์ ๋ฒ๊ฐ์ ๊ฐ๋ฉฐ ์คํํ๋ ๋ ๊ฐ์ ํ๋ก์ธ์ค๋ก ํ์ ๋๋ค. ํ๋ก์ธ์ค๋ P_0๊ณผ P_1๋ก ๊ตฌ๋ถํ์. ํธ์์ P_i๋ผ๊ณ ํํํ ๋, P_j๋ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ฅผ ๊ฐ๋ฆฌํค๊ณ j๋ 1-i์ ๊ฐ๋ค.
ํผํฐ์จ์ ํด๊ฒฐ์์ ๋ ํ๋ก์ธ์ค๊ฐ ๋ ๊ฐ์ ๋ฐ์ดํฐ ํญ๋ชฉ์ ๊ณต์ ํด์ผ ํ๋ค.
int turn;
boolean flag[2];
๋ณ์ turn์ ์๊ณ๊ตฌ์ญ์ผ๋ก ์ง์ ํ ์๋ฒ์ ๋ํ๋ธ๋ค. ๋ง์ฝ turn == i์ด๋ฉด, ํ๋ก์ธ์ค P_i๊ฐ ์๊ณ๊ตฌ์ญ์์ ์คํ๋ ์ ์๋ค.
flag ๋ฐฐ์ด์ ํ๋ก์ธ์ค๊ฐ ์๊ณ๊ตฌ์ญ์ผ๋ก ์ง์ ํ ์ค๋น๊ฐ ๋์๋ค๋ ๊ฒ์ ๋ํ๋ธ๋ค. flag[i]๊ฐ ์ฐธ์ด๋ผ๋ฉด P_i๊ฐ ์๊ณ๊ตฌ์ญ์ผ๋ก ์ง์ ํ ์ค๋น๊ฐ ๋์๋ค๋ ๊ฒ์ด๋ค.
while (true) {
flag[i] = true;
turn = j;
while (flag[j] && turn == j)
;
/* critical section */
flag[i] = false;
/* remainder section */
}
์๊ณ๊ตฌ์ญ์ผ๋ก ์ง์ ํ๊ธฐ ์ํด P_i๋ ๋จผ์ flag[i]๋ฅผ ์ฐธ์ผ๋ก ๋ง๋ค๊ณ , turn์ j๋ก ์ง์ ํ๋ค. ์ฆ, P_j๊ฐ ์๊ณ๊ตฌ์ญ์ผ๋ก ์ง์ ํ๊ธฐ๋ฅผ ์ํ๋ค๋ฉด ์ง์ ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ๋ณด์ฅํ๋ค. ๋ง์ฝ ๋ ํ๋ก์ธ์ค๊ฐ ๋์์ ์ง์ ํ๊ธฐ๋ฅผ ์ํ๋ค๋ฉด turn์ ๊ฑฐ์ ๋์์ i์ j๋ก ์ง์ ๋์ง๋ง, ๋ ์ค ์ค์ง ํ ๋ฐฐ์ ๋ง์ด ์ง์๋๋ค. ๊ฒฐ๊ตญ turn์ ๊ถ๊ทน์ ์ธ ๊ฐ์ด ๋ ์ค ๋๊ฐ ๋จผ์ ์๊ณ๊ตฌ์ญ์ผ๋ก ์ง์ ํ ๊ฒ์ธ๊ฐ๋ฅผ ๊ฒฐ์ ํ๋ค.
ํผํฐ์จ์ ํด๊ฒฐ์์ด ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ค๋ ๊ฒ์ ์ฆ๋ช ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ฌ์ค์ ๋ณด์ฌ์ผ ํ๋ค.
- ์ํธ ๋ฐฐ์ ๊ฐ ์ ๋๋ก ์ง์ผ์ง๋ค.
- ์งํ์ ๋ํ ์๊ตฌ ์กฐ๊ฑด์ ๋ง์กฑํ๋ค.
- ๋๊ธฐ ์๊ฐ์ด ํ์์ด ๊ธธ์ด์ง์ง ์๋๋ค.
1๋ฒ์ ์ฆ๋ช ํ๋ ค๋ฉด, ๊ฐ P_i๊ฐ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ๊ธฐ ์ํด์๋ ๋ฐ๋์ flag[j] == false ์ด๋ ์ง turn == i ์ฌ์ผ ํ๋ค. ๋ ํ๋ก์ธ์ค ๋ชจ๋ ์์ ์ ์๊ณ๊ตฌ์ญ์ ์ง์ ํ๋ ค๊ณ ํ๋ค๋ฉด flag[i] == flag[j] == true๊ฐ ๋์ง๋ง, turn ๋ณ์์ ๊ฐ์ด 0์ด๋ฉด์ 1์ผ ์๋ ์๊ธฐ์ P_i๊ณผ P_j๋ ๋์์ while๋ฌธ์ ํต๊ณผํ ์ ์์ ๊ฒ์ด๋ค.
2๋ฒ๊ณผ 3๋ฒ์ ์ฆ๋ช ํ๋ ค๋ฉด, P_i๊ฐ ์ค๋ก์ง flag[j] == true์ turn == j์ ์ํด while ๋ฃจํ ์์์ ๊ณตํ์ ํ ๋๋ง ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ์ง ๋ชปํ๋ค๋ ์ ์ ๋ค ์ ์๋ค.
P_j๊ฐ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ ์ค๋น๊ฐ ์ ๋์์ ๋๋ flag[j] == false ์ด๊ณ , P_i๋ ์๊ณ๊ตฌ์ญ์ ์ง์ ํ ์ ์๋ค. P_j๊ฐ flag[j]๋ฅผ true๋ก ์ง์ ํ๊ณ ์ญ์ ์์ ์ while๋ฌธ์ ์ํํ๊ฒ ๋๋ฉด ์ด๋ turn์ i์ด๊ฑฐ๋ j์ผ ๊ฒ์ด๋ค. turn == i ์ด๋ฉด P_i๊ฐ ์๊ณ๊ตฌ์ญ์ ์ง์ ํ๊ฒ ๋๊ณ , turn == j ์ด๋ฉด P_j๊ฐ ์๊ณ๊ตฌ์ญ์ ์ง์ ํ๊ฒ ๋๋ค. ๊ทธ๋ฌ๋ ์ถํ์ P_j๊ฐ ์๊ณ๊ตฌ์ญ์ ๋น ์ ธ๋์ฌ ๋ P_j๊ฐ flag[j]๋ฅผ false๋ก ์ฌ์ง์ ํ๊ณ turn ๊ฐ์ i๋ก ์ง์ ํ์ฌ P_i๊ฐ ์ง์ ํ ์ ์๊ฒ ํด์ค๋ค. P_i๊ฐ while๋ฌธ ์คํ ์ค์ turn ๊ฐ์ ๋ฐ๊ฟ ์ ์๊ธฐ ๋๋ฌธ์ P_j๊ฐ ์ง๋๋ฒ์ ์๊ณ๊ตฌ์ญ์ ์ง์ ํ๋ค๋ฉด P_i๊ฐ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ ์ ์๊ฒ ๋๋ค.
ํ์ง๋ง ํผํฐ์จ์ ํด๊ฒฐ์์ ์ต์ ์ปดํจํฐ ์ํคํ ์ฒ์์ ์๋ํ๋ค๊ณ ๋ณด์ฅ๋์ง ์๋๋ค. ์ฃผ๋ ์ด์ ๋ ์์คํ ์ฑ๋ฅ์ ํฅ์ํ๊ธฐ ์ํด ํ๋ก์ธ์ ๋ฐ ์ปดํ์ผ๋ฌ๊ฐ ์ข ์์ฑ์ด ์๋ ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ์์ ์ ์ฌ์ ๋ ฌ ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ฅผ ๋ค์ด, ๋ ์ค๋ ๋ ๊ฐ์ ๊ณต์ ๋๋ ๋ค์ ๋ฐ์ดํฐ๋ฅผ ๊ณ ๋ คํ์.
boolean flag = fasle;
int x = 0;
์ฌ๊ธฐ์ ์ค๋ ๋1์ ๋ค์ ๋ช ๋ น๋ฌธ์ ์ํํ๋ค.
while(!flag)
;
print x;
๊ทธ๋ฆฌ๊ณ ์ค๋ ๋2๋ ๋ค์ ๋ช ๋ น๋ฌธ์ ์ํํ๋ค.
x = 100;
flag = true;
์์๋๋ ๋์์ ์ค๋ ๋1์ด ๋ณ์ x์ ๋ํด ๊ฐ 100์ ์ถ๋ ฅํ๋ ๊ฒ์ด๋ค. ํ์ง๋ง ๋ณ์ flag์ x ์ฌ์ด์ ๋ฐ์ดํฐ ์ข ์์ฑ์ด ์์ผ๋ฏ๋ก ํ๋ก์ธ์๊ฐ ์ค๋ ๋2์ ๋ช ๋ น์ด๋ฅผ ์ฌ์ ๋ ฌํ์ฌ x=100์ ๋ฐฐ์ ํ๊ธฐ ์ ์ flag๊ฐ true๋ก ์ง์ ๋ ์ ์๊ณ , ์ด ์ํฉ์์ ์ค๋ ๋1์ ๋ณ์ x์ ๋ํด 0์ ์ถ๋ ฅํ ์ ์๋ค.
๐ 6.4 ๋๊ธฐํ๋ฅผ ์ํ ํ๋์จ์ด ์ง์ Hardware Support for Synchronization
์ํํธ์จ์ด ๊ธฐ๋ฐ ํด๊ฒฐ์ฑ ์ ์ต์ ์ปดํจํฐ ์ํคํ ์ฒ์์ ์๋ํ์ง ์์ ์ ์๋ค. ๊ทธ๋ ๊ธฐ์ ์๊ณ๊ตฌ์ญ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ง์์ ์ ๊ณตํ๋ ์ธ ๊ฐ์ง ํ๋์จ์ด ๋ช ๋ น์ด์ ๋ํด ์์๋ณด์.
6.4.1 ๋ฉ๋ชจ๋ฆฌ ์ฅ๋ฒฝ Memory Barriers
6.3์ ์์ ๋ดค๋ฏ์ด, ์์คํ ์ ๋ช ๋ น์ด์ ์์๋ฅผ ์ฌ์ ๋ ฌ ํ ์ ์๊ธฐ์ ๋ฐ์ดํฐ์ ์ ๋ขฐ์ฑ์ด ๋จ์ด์ง ์ ์๋ค. ์ปดํจํฐ ์ํคํ ์ฒ๊ฐ ์์ฉ ํ๋ก๊ทธ๋จ์๊ฒ ์ ๊ณตํ ๋ฉ๋ชจ๋ฆฌ ๋ณด์ฅ์ ๊ฒฐ์ ํ๋ ๋ฐฉ์์ ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ธ memory model์ด๋ผ๊ณ ํ๋๋ฐ, ์ผ๋ฐ์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ธ์ ๋ ๊ฐ์ง๋ก ๋ถ๋ฅ๋๋ค.
- ๊ฐํ ์์ strongly ordered : ํ ํ๋ก์ธ์์ ๋ฉ๋ชจ๋ฆฌ ๋ณ๊ฒฝ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅธ ๋ชจ๋ ํ๋ก์ธ์์ ์ฆ์ ๋ณด์.
- ์ฝํ ์์ weakly ordered : ํ ํ๋ก์ธ์์ ๋ฉ๋ชจ๋ฆฌ ๋ณ๊ฒฝ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅธ ํ๋ก์ธ์์ ์ฆ์ ๋ณด์ด์ง ์์.
๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ธ์ ํ๋ก์ธ์ ์ ํ์ ๋ฐ๋ผ ๋ค๋ฅด๋ฏ๋ก ์ปค๋ ๊ฐ๋ฐ์๋ ๊ณต์ ๋ฉ๋ชจ๋ฆฌ ๋ค์ค ์ฒ๋ฆฌ๊ธฐ์์ ๋ฉ๋ชจ๋ฆฌ ๋ณ๊ฒฝ์ ๊ฐ์์ฑ์ ๋ํ ๊ฐ์ ์ ํ ์ ์๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ปดํจํฐ ์ํคํ ์ฒ๋ ๋ฉ๋ชจ๋ฆฌ์ ๋ชจ๋ ๋ณ๊ฒฝ ์ฌํญ์ ๋ค๋ฅธ ๋ชจ๋ ํ๋ก์ธ์๋ก ์ ํํ๋ ๊ฒ์ ๋ณด์ฅํ๋๋ฐ, ์ด๋ฌํ ๋ช ๋ น์ด๋ฅผ ๋ฉ๋ชจ๋ฆฌ ์ฅ๋ฒฝ memory barriers ๋๋ ๋ฉ๋ชจ๋ฆฌ ํ์ค memory fences๋ผ๊ณ ๋ถ๋ฅธ๋ค.
๋ฉ๋ชจ๋ฆฌ ์ฅ๋ฒฝ ๋ช ๋ น์ด๊ฐ ์คํ๋ ๋, ์์คํ ์ ๋ชจ๋ ์ ์ฌ/์ ์ฅ ์ฐ์ฐ์ด ๋ค์ ์ ์ฌ/์ ์ฅ ์ฐ์ฐ์ด ์ํ๋๊ธฐ ์ ์ ์๋ฃ๋๋๋ก ํ๊ธฐ์, ๋ช ๋ น์ด ์ฌ์ ๋ ฌ๋๋๋ผ๋ ํฅํ ์ ์ฌ/์ ์ฅ ์์ ์ด ์ํ๋๊ธฐ ์ ์ ์ ์ฅ ์์ ์ด ๋ฉ๋ชจ๋ฆฌ์์ ์๋ฃ๋์ด ๋ค๋ฅธ ํ๋ก์ธ์์๊ฒ๋ ์ฆ์ ๋ฐ์์ด ๋๋๋ก ํ๋ค.
๋ช ๋ น์ด๋ฅผ ์ฌ์ ๋ ฌํ์ฌ ์๋ชป๋ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค ์ ์์๋ ๋ฌธ์ ๋ก ๋์๊ฐ๋ณด์.
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ์ ์์๋๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค๋๋ก ๋ฉ๋ชจ๋ฆฌ ์ฅ๋ฒฝ์ ์ฌ์ฉํด๋ณด์.
์ค๋ ๋1์ ๋ฉ๋ชจ๋ฆฌ ์ฅ๋ฒฝ ์ฐ์ฐ์ ์ถ๊ฐํ๋ฉด
while(!flag)
memory_barrier();
print x;
flag ๊ฐ์ด x ๊ฐ๋ณด๋ค ๋จผ์ ์ ์ฌ๋๋๋ก ๋ณด์ฅํ๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก ์ค๋ ๋2์๋ ๋ฉ๋ชจ๋ฆฌ ์ฅ๋ฒฝ ์ฐ์ฐ์ ์ถ๊ฐํ๋ฉด
x = 100;
memory_barrier();
flag = true;
flag์ ๋ฐฐ์ ํ๊ธฐ ์ ์ x์ ๋ํ ๋ฐฐ์ ์ด ๋จผ์ ์คํ๋๋๋ก ํ ์ ์๋ค.
๋ฉ๋ชจ๋ฆฌ ์ฅ๋ฒฝ์ ๋งค์ฐ ๋ฎ์ ์์ค์ ์ฐ์ฐ์ผ๋ก ๊ฐ์ฃผํ๋ฉฐ ์ผ๋ฐ์ ์ผ๋ก ์ํธ ๋ฐฐ์ ๋ฅผ ๋ณด์ฅํ๋ ํน์ ์ฝ๋๋ฅผ ์์ฑํ ๋ ์ปค๋ ๊ฐ๋ฐ์๋ง ์ฌ์ฉํ๋ค.
6.4.2 ํ๋์จ์ด ๋ช ๋ น์ด Hardware Instructions
๋๋ถ๋ถ์ ํ๋ ์ปดํจํฐ ์์คํ ์์๋ ์์์ ์ผ๋ก atomically ์๋์ ๋ด์ฉ๋ฌผ์ ํ ์คํธํ๊ณ ๋ณ๊ฒฝํ๊ฑฐ๋ ๋ ์๋์ ๋ด์ฉ์ ๊ตํ swapํ ์ ์๊ฒ ํ๋ ํน์ํ ํ๋์จ์ด ๋ช ๋ น์ด๋ฅผ ์ ๊ณตํ๋ค. ์ด ํน์ํ ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ ์๊ณ๊ตฌ์ญ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ค. test_and_set()๊ณผ compare_and_swap() ๋ช ๋ น์ด๋ฅผ ์ค์ฌ์ผ๋ก ์ดํด๋ณด์.
test_and_set() ๋ช ๋ น์ด๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์ํ ์ ์๋ค.
boolean test_and_set(boolean *target) {
boolean rv = *target;
*target = true;
return rv;
}
์ค์ํ ํน์ง์ ์ด ๋ช ๋ น์ด๊ฐ ์์์ ์ผ๋ก ์คํ๋๊ธฐ์ ๋ง์ฝ ๋ test_and_set() ๋ช ๋ น์ด๊ฐ (์๋ก ๋ค๋ฅธ ์ฝ์ด์์) ๋์์ ์คํ๋๋๋ผ๋ ์์์ ์์๋ก ์์ฐจ์ ์ผ๋ก ์คํ๋ ๊ฒ์ด๋ค. ๋ง์ฝ ๊ธฐ๊ณ๊ฐ test_and_set() ๋ช ๋ น์ ์ง์ํ๋ค๋ฉด, false๋ก ์ด๊ธฐํ๋๋ lock์ด๋ผ๋ boolean ๋ณ์๋ฅผ ์ ์ธํ์ฌ ์ํธ ๋ฐฐ์ ๋ฅผ ๊ตฌํํ ์ ์๋ค. ํ๋ก์ธ์ค P_i์ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ด๋ค.
do {
while (test_and_set(&lock))
; /* do nothing */
/* critical section */
lock = false;
/* remainder section */
} while (true);
compare_and_swap() ๋ช ๋ น์ด(CAS)๋ test_and_set() ๋ช ๋ น์ด์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ ๊ฐ์ ์๋์ ๋ํด ์์์ ์ธ ์ฐ์ฐ์ ํ์ง๋ง ๋ ์๋์ ๋ด์ฉ ๊ตํ swap์ ๊ธฐ๋ฐ์ ๋ ๋ค๋ฅธ ๊ธฐ๋ฒ์ ์ฌ์ฉํ๋ค. CAS ๋ช ๋ น์ด๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋ ์ธ ๊ฐ์ง ์ฐ์ฐ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ฒ๋ฆฌ๋๋ค.
int compare_and_swap(int *value, int expected, int new_value) {
int temp = *value;
if (*value == expected)
*value = new_value;
return temp;
}
ํผ์ฐ์ฐ์ value๋ ์ค์ง (*value == expected) ์์์ด ์ฐธ์ผ ๋๋ง new_value๋ก ์ง์ ๋๋ค. ์ค์ํ ๊ฒ์ ๋ช ๋ น์ด ์์์ ์ผ๋ก ์คํ๋๋ฏ๋ก ๋ CAS๊ฐ ์๋ก ๋ค๋ฅธ ์ฝ์ด์์ ๋์์ ์คํ๋๋ฉด ์์์ ์์๋ก ์์ฐจ์ ์ผ๋ก ์คํ๋๋ค๋ ๊ฒ์ด๋ค.
ํ๋ก์ธ์ค P_i์ ๋ํด CAS๋ฅผ ํตํ ์ํธ ๋ฐฐ์ ๋ ๋ค์๊ณผ ๊ฐ์ด ์ฒ๋ฆฌ๋ ์ ์๋ค.
while(true) {
while(compare_and_swap(&lock, 0, 1) != 0)
; /* do nothing */
/* critical section */
lock = 0;
/* remainder section */
}
์ ์ญ๋ณ์ lock์ด ์ ์ธ๋๊ณ 0์ผ๋ก ์ด๊ธฐํ๋๋ค. compare_and_swap()์ ์ฒ์ ํธ์ถํ ํ๋ก์ธ์ค๊ฐ lock์ 1๋ก ์ค์ ํ๋ค. ์๋ lock์ ๊ฐ์ด ์์๊ฐ 0๊ณผ ๊ฐ์ผ๋ฏ๋ก ํ๋ก์ธ์ค๋ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ๋ค. ์ดํ์ compare_and_swap() ํธ์ถ์ ํ์ฌ lock์ ๊ฐ์ด ์์๊ฐ 0๊ณผ ๊ฐ์ง ์๊ธฐ ๋๋ฌธ์ ์ฑ๊ณตํ์ง ๋ชปํ๋ค. ํ๋ก์ธ์ค๊ฐ ์๊ณ๊ตฌ์ญ์ ๋ฒ์ด๋ ๋๋ lock์ 0์ผ๋ก ๋ณ๊ฒฝํ๊ณ , ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ ์ ์๊ฒ ํ์ฉํ๋ค.
์ ์๊ณ ๋ฆฌ์ฆ์ ์ํธ ๋ฐฐ์ ์กฐ๊ฑด์ ๋ง์กฑํ์ง๋ง, ํ์ ๋ ๋๊ธฐ ์กฐ๊ฑด์ ๋ง์กฑ์ํค์ง๋ ๋ชปํ๋ค. ๋ค์ ์ฝ๋๋ compare_and_swap() ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ๋ฉด์ ๋ชจ๋ ์๊ณ๊ตฌ์ญ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
while(true) {
waiting[i] = true;
key = 1;
while(waiting[i] && key == 1)
key = compare_and_swap(&lock, 0, 1);
waiting[i] = false;
/* critical section */
j = (i+1) % n;
while((j != i) && !waiting[j])
j = (j+1) % n;
if(j == i)
lock = 0;
else
waiting[j] = false;
/* remainder section */
}
6.4.3 ์์์ ๋ณ์ Atomic Variables
์ผ๋ฐ์ ์ผ๋ก compare_and_swap() ๋ช ๋ น์ด๋ ์ํธ ๋ฐฐ์ ๋ฅผ ์ ๊ณตํ๊ธฐ ์ํด ์ง์ ์ฌ์ฉ๋์ง ์๊ณ , ์คํ๋ ค ์๊ณ๊ตฌ์ญ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ค๋ฅธ ๋๊ตฌ๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํ ๊ธฐ๋ณธ ๊ตฌ์ฑ์์๋ก ์ฌ์ฉ๋๋ค. ๊ทธ๋ฌํ ๋๊ตฌ ์ค ํ๋๋ ์์์ ๋ณ์ atomic variable๋ก, ์ ์ ๋ฐ ๋ถ์ธ๊ณผ ๊ฐ์ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ์ ํ์ ๋ํ ์์์ ์ฐ์ฐ์ ์ ๊ณตํ๋ค.
๐ 6.5 Mutex Locks
์๊ณ๊ตฌ์ญ ๋ฌธ์ ์ ๋ํ ํ๋์จ์ด ๊ธฐ๋ฐ ํด๊ฒฐ์ฑ ์ ๋ณต์กํ ๋ฟ๋ง ์๋๋ผ ์์ฉ ํ๋ก๊ทธ๋๋จธ๋ ์ฌ์ฉํ ์๊ฐ ์๋ค. ๋์ ์ด์์ฒด์ ์ค๊ณ์๋ค์ ์๊ณ๊ตฌ์ญ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์์ ์์ค ์ํํธ์จ์ด ๋๊ตฌ๋ค์ ๊ฐ๋ฐํ์๊ณ , ๊ฐ์ฅ ๊ฐ๋จํ ๋๊ตฌ๊ฐ ๋ฐ๋ก mutex lock์ด๋ค. mutex lock์ผ๋ก ์๊ณ๊ตฌ์ญ์ ๋ณดํธํ๊ณ , ๋ฐ๋ผ์ ๊ฒฝ์ ์กฐ๊ฑด์ ๋ฐฉ์งํ๊ธฐ ์ํด mutex lock์ ์ฌ์ฉํ๋ค. ์ฆ, ํ๋ก์ธ์ค๋ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ๊ธฐ ์ ์ ๋ฐ๋์ ๋ฝ์ ํ๋ํด์ผ ํ๊ณ , ์๊ณ๊ตฌ์ญ์์ ๋น ์ ธ๋์ฌ ๋ ๋ฝ์ ๋ฐํํด์ผ ํ๋ค.
์์ ๊ทธ๋ฆผ์์์ฒ๋ผ acquire() ํจ์๊ฐ ๋ฝ์ ํ๋ํ๊ณ , release() ํจ์๊ฐ ๋ฝ์ ๋ฐํํ๋ค.
mutex lock์ available์ด๋ผ๋ boolean ๋ณ์๋ฅผ ๊ฐ์ง๋๋ฐ, ์ด ๋ณ์ ๊ฐ์ด ๋ฝ์ ๊ฐ์ฉ ์ฌ๋ถ๋ฅผ ํ์ํ๋ค.
acquire()์ ๋ค์๊ณผ ๊ฐ์ด ์ ์ํ๋ค.
acquire() {
while (!available)
; /* busy wait */
available = false;
}
release()๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์ํ๋ค.
release() {
available = true;
}
acquire()๊ณผ release() ํจ์ ํธ์ถ์ ์์์ ์ผ๋ก ์ํ๋์ด์ผ ํ๋ค. ๋ฐ๋ผ์ mutex lock์ CAS๋ฅผ ํตํด ๊ตฌํ๋ ์ ์๋ค.
์ด๋ ๊ฒ ๊ตฌํํ์ ๋์ ์ต๋ ๋จ์ ์ ๋ฐ๋ก ๋ฐ์ ๋๊ธฐ busy waiting์ ํด์ผ ํ๋ค๋ ๊ฒ์ด๋ค. ํ๋ก์ธ์ค๊ฐ ์๊ณ๊ตฌ์ญ์ ์๋ ๋์ ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ๊ธฐ๋ฅผ ์ํ๋ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ค์ acquire() ํจ์๋ฅผ ํธ์ถํ๋ ๋ฐ๋ณต๋ฌธ์ ๊ณ์ ์คํํด์ผ ํ๊ณ , ์ด๋ฌํ ๋ฃจํ์ ์คํ์ ํ๋์ CPU ์ฝ์ด๊ฐ ์ฌ๋ฌ ํ๋ก์ธ์ค์ ๊ณต์ ๋๋ ๋ฉํฐํ๋ก๊ทธ๋๋ฐ ์์คํ ์์ ๋ถ๋ช ํ ๋ฌธ์ ๊ฐ ๋๋ค.
๐ 6.6 Semaphore
mutex์ ์ ์ฌํ๊ฒ ๋์ํ์ง๋ง ํ๋ก์ธ์ค๋ค์ด ์์ ๋ค์ ํ๋์ ๋ ์ ๊ตํ๊ฒ ๋๊ธฐํํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ ๋๊ตฌ์ ๋ํด ์ดํด๋ณด์.
์ธ๋งํฌ S๋ ์ ์ ๋ณ์๋ก์, ์ด๊ธฐํ๋ฅผ ์ ์ธํ๊ณ ๋ ๋จ์ง ๋ ๊ฐ์ง์ ํ์ค ์์์ ์ฐ์ฐ wait()์ signal()๋ก๋ง ์ ๊ทผํ ์ ์๋ค.
wait()์ ์ ์๋ ๋ค์๊ณผ ๊ฐ๋ค.
wait(S) {
while(S <= 0)
; // busy wait
S--;
}
signal()์ ์ ์๋ ๋ค์๊ณผ ๊ฐ๋ค.
signal(S) {
S++;
}
wait()์ signal() ์ฐ์ฐ ์ ์ธ๋งํฌ์ ์ ์ ๊ฐ์ ๋ณ๊ฒฝํ๋ ์ฐ์ฐ์ ๋ฐ๋์ ์์์ ์ผ๋ก ์ํ๋์ด์ผ ํ๋ค. ์ฆ, ํ ์ค๋ ๋๊ฐ ์ธ๋งํฌ ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด, ๋ค๋ฅธ ์ด๋ค ์ค๋ ๋๋ ๋์์ ๋์ผํ ์ธ๋งํฌ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
