[OS] ๋ฉํฐ์ค๋ ๋์์ ๊ฒฝ์ ์ํ ํด๊ฒฐ: ์ํธ ๋ฐฐ์ (๋ฎคํ ์ค์ ์ธ๋งํฌ์ด)
๐ ์ค๋ ์ฃผ์ ์ธ ๊ฒฝ์ ์ํ์ ์ํธ ๋ฐฐ์ ๋ ๋ฉํฐ์ค๋ ๋ ์ธ์๋ ๋ฉํฐํ๋ก์ธ์ค์์๋ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์ด์ง๋ง
์ ๊ฐ ๋ฉํฐ์ค๋ ๋์ ๋ํด ๋ฐฐ์ฐ๋ฉฐ ์ ๋ฆฌํ ๋ด์ฉ์ผ๋ก, ๋ฉํฐ์ค๋ ๋์ ๋ํด์๋ง ์ค์ ์ ์ผ๋ก ์ธ๊ธํ์ต๋๋ค.
์ฐฉ์ค๊ฐ ์์ผ์๊ธธ!
โ ๋ฉํฐ์ค๋ ๋๋?
์ด์ ๊ธ์์ ์ค๋ ๋์ ๊ฐ๋ ์ ์ดํด๋ดค์ต๋๋ค.
โ๏ธ ํ๋ก์ธ์ค / ์ค๋ ๋ ๊ฐ๋ ์ ๋ฆฌ
๐ ์์ฝํ๋ก๊ทธ๋จ: ์ด๋ ์์ ์ ํ๊ธฐ ์ํด ์คํ๋ ์ ์๋ ํ์ผํ๋ก์ธ์ค: ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ผ๊ฐ๊ณ , ์ด์์ฒด์ ๋ก๋ถํฐ CPU๋ฅผ ํ ๋น๋ฐ์ ์คํ ์ค์ธ ํ๋ก๊ทธ๋จ์ค๋ ๋: ํ๋ก์ธ์ค ๋ด์์ ๋ ๋ฆฝ์ ์ผ๋ก ์คํ๋๋
syleeblog.tistory.com
๋ฉํฐ์ค๋ ๋๋ ํ๋์ ํ๋ก์ธ์ค ์์ ์ฌ๋ฌ ๊ฐ์ ์ค๋ ๋๊ฐ ์๋ ์ํ๋ฅผ ๋งํฉ๋๋ค.
์ฆ, ํ๋์ ํ๋ก์ธ์ค ์์์ ๋ ๊ฐ์ง ์ด์์ ์์ ์ ํ ์ ์์ต๋๋ค.
ํฌ๋กฌ์์ ์ฌ๋ฌ ์ฐฝ์ ๋์ ๊ฐ์ ์์ ํ ์ ์๋ฏ์ด
๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์๋ ์ฌ๋ฌ ์์ ์ ๋์์, ๋ ๋ฆฝ์ ์ผ๋ก ์ํํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ์นด์นด์คํก์์ ํ์ผ์ ์ ์กํ๋ ๋ฐ ๋ช ์ด๊ฐ ๊ฑธ๋ฆฌ๊ธฐ๋ ํ์ง๋ง, ๊ทธ ์๊ฐ ๋์ ์ฌ์ฉ์๋ ์ ์ก์ด ๋๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ ์๋๋ผ ์๋ก์ด ํก์ ๋ณด๋ด๋ ๋ฑ์ ๋ค๋ฅธ ํ๋์ ์์ ๋กญ๊ฒ ํ ์ ์์ต๋๋ค.
๋ํ ์๋ก ๋ณ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ฐ์ง๋ ํ๋ก์ธ์ค์ ๋ฌ๋ฆฌ
์ค๋ ๋๋ผ๋ฆฌ๋ ํ๋ก์ธ์ค ๋ด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ผ๋ถ ๊ณต์ ํ๊ธฐ ๋๋ฌธ์ ๋ฉํฐ ํ๋ก์ธ์ค์ ๋นํด ์์๊ณผ ๊ณต๊ฐ์ด ์ ์ฝ๋๋ ํจ๊ณผ๊ฐ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ๋์์ ์ ๊ทผํ๊ณ ์คํ๋๋ ํ๋ฆ์ด ๋ง๋ค๋ ๊ฒ์ ๊ณต์ ์์์ ๋๋ฌ์ผ ๋ฌธ์ ์ ๊ฐ๋ฅ์ฑ๋ ์ปค์ง๋ค๋ ๋ป์ด๊ธฐ๋ ํฉ๋๋ค.
๊ทธ ๋ํ์ ์ธ ๋ฌธ์ ๋ก ๊ต์ฐฉ ์ํ(Deadlock), ๊ธฐ์ ์ํ(Starvation), ๊ฒฝ์ ์ํ(Race Condition) ๋ฑ์ด ์๋๋ฐ
์ด ๊ธ์์๋ ๊ฒฝ์ ์ํ(Race Condition)์ ๋ํด ์์ธํ ๋ค๋ค๋ณด๊ฒ ์ต๋๋ค.
๐ ๊ฒฝ์ ์ํ (Race Condition)
๊ฒฝ์ ์ํ๋ ๋ ์ด์์ ์ค๋ ๋๊ฐ ๊ณต์ ๋ ์์์ ๋ํด ๋์์ ์ ๊ทผํ๋ฉด์ ์คํ ์์์ ๋ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง๋ ๋ฌธ์ ๋ฅผ ๋งํฉ๋๋ค.
์๋ฅผ ๋ค์ด ๋ณผ๊น์?
public class Counter {
private int count = 0;
public void increment() {
count++;
}
public int getCount() {
return count;
}
}
์์ increment() ๋ฉ์๋๋ ๋จ์ํ count๋ฅผ 1 ์ฆ๊ฐ์ํค๋ ์ฝ๋์ ๋๋ค.
์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ด ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
});
๋ ๊ฐ์ ์ค๋ ๋์์ ๊ฐ๊ฐ 1000๋ฒ์ฉ ์ฆ๊ฐ์์ผฐ๋๋ฐ
๊ฒฐ๊ณผ๊ฐ 2000๋ณด๋ค ์์ ์ ์์ต๋๋ค.
๋ฌธ์ ๋ count++์ด๋ ๋์์ด ์ฌ์ค ์ธ ๊ฐ์ ๋์์ผ๋ก ๋๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
- count ๊ฐ์ ์ฝ๋๋ค
- 1์ ๋ํ๋ค
- ๊ฒฐ๊ณผ๋ฅผ ๋ค์ count์ ์ ์ฅํ๋ค
์ด ์ธ ๋์ ์ค๊ฐ์ ๋ค๋ฅธ ์ค๋ ๋๊ฐ ๋ผ์ด๋ค๋ฉด, count ๊ฐ์ ์๋ฑํ๊ฒ ์ฆ๊ฐํ๊ฑฐ๋ ๊ฑด๋๋ฐ๊ฒ ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ ์ค๋ ๋๊ฐ ์๋์ ๊ฐ์ ์์๋ก ์คํ๋๋ค๊ณ ํด๋ด ์๋ค.
- ์ค๋ ๋ A: count ๊ฐ์ ์ฝ์ → (count == 0)
- ์ค๋ ๋ B: count ๊ฐ์ ์ฝ์ → (count == 0)
- ์ค๋ ๋ A: 1์ ๋ํด 1 ์ ์ฅ
- ์ค๋ ๋ B: 1์ ๋ํด 1 ์ ์ฅ
๊ฒฐ๊ณผ์ ์ผ๋ก ๋ ๋ฒ ์ฆ๊ฐํ์ง๋ง ์ค์ ๊ฐ์ 1์ ๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด, ๊ณต์ ์์์ ๋ํด ์ค๋ ๋๋ค์ด ์์๋๋ก ์ ๊ทผํ๋๋ก "๋๊ธฐํ" ์์ ์ด ํ์ํฉ๋๋ค.
๐งช ํด๊ฒฐ ์ ๋ต
๊ฒฝ์ ์ํ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ผ๋ก ์ํธ๋ฐฐ์ ์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.
๐ก ์ํธ๋ฐฐ์ (Mutual Exclusion)
์ผ๋ฐ์ ์ธ ํ๋ก์ธ์ค ๋ด ์ฝ๋ ๊ตฌ์กฐ์ ๋๋ค.
์ฝ๋ ์ค ๊ณต์ ์์์ ์ ๊ทผํ๋ ๊ตฌ์ญ์ ์๊ณ ๊ตฌ์ญ(critical section)์ด๋ผ๊ณ ํฉ๋๋ค.
๐ ์๊ณ ๊ตฌ์ญ์ด๋? (critical section?)
๋ ์ด์์ ํ๋ก์ธ์ค์์ ๋์์ ์ ๊ทผํด์๋ ์ ๋๋ ๊ณต์ ์์์ ์ ๊ทผํ๋ ์ฝ๋ ๊ตฌ์ญ
(a piece of code that accesses a shared resources(data structure or device) that must not be concurrently accessed by more than one processes.)
์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์๊ณ ๊ตฌ์ญ์ ์ง์ ํ๋ค๋ฉด ๊ฒฝ์ ์ํ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋์ ์ด๋ฅผ ๋ฐฉ์งํ๋ ๋ฌธ์ ๋ฅผ ์๊ณ ๊ตฌ์ญ ๋ฌธ์ (Critical Section Problem)์ด๋ผ๊ณ ๋ถ๋ฅด๊ธฐ๋ ํฉ๋๋ค.
์ด๋ฅผ ๋ง๊ธฐ ์ํด ์ค๋ ๋๊ฐ ์๊ณ ๊ตฌ์ญ์ ๋ค์ด๊ฐ๊ธฐ ์ ์
์์ ์ด ์๊ณ ๊ตฌ์ญ์์ ์์ ํ๋ ๋์ ๋ค๋ฅธ ์ค๋ ๋๋ค์ด ์ง์ ํ์ง ๋ชปํ๋๋ก lock์ ์ค์ ํ๊ณ ,
์๊ณ ๊ตฌ์ญ์์์ ์์ ์ด ๋๋๋ฉด lock์ ํด์ ํ๋ ๋์์ด ํ์ํฉ๋๋ค.
์ฆ, ์ด๋ฏธ ํ ์ค๋ ๋๊ฐ ์๊ณ ๊ตฌ์ญ์์ ์์ ์ค์ด๋ผ๋ฉด ๋ค๋ฅธ ์ค๋ ๋๋ ์๊ณ ๊ตฌ์ญ์ ์ง์ ํ๋ฉด ์ ๋ฉ๋๋ค.
์ด๋ฅผ ์ํธ ๋ฐฐ์ (Mutual Exclusion)์ด๋ผ๊ณ ํฉ๋๋ค.
๋ค์์ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ์ํธ๋ฐฐ์ ๋ฅผ ๊ตฌํํ๋ ๋ํ์ ์ธ ๋ ๊ฐ์ง ๋๊ธฐํ ๋ฉ์ปค๋์ฆ
๋ฎคํ ์ค์ ์ธ๋งํฌ์ด์ ๋ํด ์ดํด๋ด ์๋ค.
โ ๋ฎคํ ์ค(Mutex)
"ํ ๋ฒ์ ํ๋๋ง ๋ค์ด์ฌ ์ ์๋ค"
๊ณต์ ์์์ ๋ํด ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผ ๊ฐ๋ฅํ ์ ๋ต์ ๋๋ค.
ํ ์ค๋ ๋๊ฐ ์์์ ์ ๊ทผํ๋ฉด ํ๋ฆด ๋๊น์ง ๋ฝ(lock)์ด ๊ฑธ๋ฆฝ๋๋ค.
์ด ๋ฝ์ ํ ์ ์๋ ๊ฑด ๋ฝ์ ๊ฑด ํด๋น ์ค๋ ๋ ๋ฟ์ ๋๋ค.
์ด ์์์ ์ ๊ทผํ๊ณ ์ ํ๋ ๋๋จธ์ง ์ค๋ ๋๋ ๋ฝ์ด ํ๋ฆด ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค.
Java์์๋ ์๋์ ๊ฐ์ด synchronized ํค์๋๋ฅผ ๋ฉ์๋์ ๋ถ์ฌ increment() ๋ฉ์๋ ์คํ ์ ํ๋ก ๋ฝ์ ๊ฑธ ์ ์์ต๋๋ค.
public synchronized void increment() {
count++;
}
synchronized ํค์๋๋ฅผ ์ด์ฉํ ๊ฒฝ์ฐ ์์ ์ด ๋๋ ์ค๋ ๋๊ฐ ๋ฝ์ ๋ฐํํ ๋, ๋ค์์ผ๋ก ๋ฝ์ ํ๋ํ ์ค๋ ๋๊ฐ ์ด๋ค ์ค๋ ๋์ผ์ง์ ๋ํ ๋ณด์ฅ์ด ์๊ธฐ ๋๋ฌธ์
์ด๋ค ์ค๋ ๋๋ ๋ฝ์ ํ๋ํ์ง ๋ชปํ๊ณ , ๊ณ์ ์ ๊ทผ์ ๊ธฐ๋ค๋ฆฌ๋ ๊ธฐ์ ์ํ๊ฐ ๋ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค.
(์ผ๋ฐ์ ์ผ๋ก๋ JVM์ด ๊ณต์ ํ๊ฒ ๋ฝ์ ๋ถ๋ฐฐํ๋ ค ํฉ๋๋ค.)
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ช ์์ ๋ฝ์ ์ฌ์ฉํ๊ธฐ๋ ํฉ๋๋ค. ๋ํ์ ์ธ ์๋ก Java์ ReentrantLock์ด ์์ต๋๋ค.
private final ReentrantLock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
syncronized ํค์๋์ ๋ช ์์ ๋ฝ ๋ชจ๋ ๋ค๋ฅธ ์ค๋ ๋์์ ํ์ธํ ์ ์๋ ๊ฒ ์๋๋ผ ํ๋์ ์ค๋ ๋ ๋ด์์๋ง ์ผ์ด๋๋ ์ผ์ ๋๋ค.
๋ฐ๋ผ์ ๋ฎคํ ์ค์์๋ ๋ฝ์ ํ๋ํ ์ค๋ ๋๋ง์ด ๋ฝ์ ํด์ ํ ์ ์์ต๋๋ค.
์ด์ฒ๋ผ ๋ฎคํ ์ค์์ ๋ฝ์ ์์ ๊ถ์ ๊ฐ๋ ์ด ์์ต๋๋ค.
๋ฎคํ ์ค์ ๋ชฉ์ ์ ํ ์ค๋ ๋๊ฐ ์ด๋ค ๊ณต์ ์์์ ๋ํด ๋ ์ ์ ์ผ๋ก ์์ ์ ๋๋ง์น ๋๊น์ง ๋ณดํธํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
๐ ๋ฎคํ ์ค์์ ํต์ฌ์ ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผ ๊ฐ๋ฅํ๋๋ก ๋ณด์ฅํ๋ค๋ ์ ์ ๋๋ค.
โ ์ธ๋งํฌ์ด(Semaphore)
์ธ๋งํฌ์ด ์ญ์ ๊ณต์ ์์์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ์ ๊ทผ๋๋ ๊ฒ์ ๋ง๋ ๋ฐฉ๋ฒ์ด์ง๋ง
๋ฎคํ ์ค์ ๋ค๋ฅด๊ฒ ๋ฐ๋์ ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผํ ์ ์๋ ๊ฒ์ ์๋๋๋ค.
์ธ๋งํฌ์ด์์๋ ๋์์ ์ ํด์ง ๊ฐ์๋งํผ์ ์ค๋ ๋๊ฐ ๊ณต์ ์์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
Semaphore๋ผ๋ ์ ์ํ ์นด์ดํฐ ๋ณ์(๋ณดํต s๋ก ํ์)๋ฅผ ์ด์ฉํ์ฌ ๋์์ ๊ณต์ ์์์ ์ ๊ทผํ ์ ์๋ ์ค๋ ๋์ ์๋ฅผ ์ ํํฉ๋๋ค.
์ฒ์์ ๊ณต์ ์์์ ์ ๊ทผํ ์ ์๋ ๋์ ์ค๋ ๋ ์๋ฅผ N๊ฐ๋ก ์ ํ๋ฉด, ์ต๋ N๊ฐ๋ง ๋์์ ์๊ณ ๊ตฌ์ญ์ ์ง์ ํ ์ ์๊ณ ,
๊ทธ๋ณด๋ค ๋ ๋ง์ ์ค๋ ๋๊ฐ ์ ๊ทผํ๋ ค๊ณ ํ๋ฉด ๋จผ์ ๋ค์ด๊ฐ ์๋ ์ค๋ ๋๊ฐ ๋์ฌ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํฉ๋๋ค.
"์๋.. ๋์์ ํ๋์ ์ค๋ ๋๋ง ์๊ณ ๊ตฌ์ญ์ ๋ค์ด๊ฐ์ผ ํ๋ค๋ฉด์์?! ์ธ๋งํฌ์ด๊ฐ ์ํธ๋ฐฐ์ ์ธ ๊ฑฐ ๋ง์์?"
๊ฒฝ์ ์ํ๋ฅผ ๋ง๊ธฐ ์ํด ํ ์์ ์ ์ค์ง ํ๋์ ์ค๋ ๋๋ง ๊ณต์ ์์์ ์ ๊ทผํ ์ ์๋๋ก ์ ํํ๋ ๊ฒ์ด ์ํธ ๋ฐฐ์ ์ ๋๋ค.
์ํธ ๋ฐฐ์ ๋ฅผ ๊ตฌํํ๋ ๋๊ตฌ๋ก ์ค๋ ์ดํด๋ณธ ๋ฎคํ ์ค์ ์ธ๋งํฌ์ด ๋ฑ์ด ์๋๊ฑฐ์ฃ .
๋ง์ฝ ์ธ๋งํฌ์ด์์ ๋์์ ๊ณต์ ์์์ ์ ๊ทผํ ์ ์๋ ์ค๋ ๋์ ๊ฐ์๋ฅผ "1๊ฐ"๋ก ์ค์ ํ๋ค๋ฉด
๋ฎคํ ์ค์ฒ๋ผ ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง ๋ค์ด๊ฐ๊ฒ ์ฃ ? ์ด๋ฌํ ์ธ๋งํฌ์ด๋ฅผ Binary Semaphore๋ผ๊ณ ํฉ๋๋ค.
Binary Semaphore๋ก ๊ตฌํํ๋ฉด ์ํธ ๋ฐฐ์ ๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค.
์ค๋ ๋ฐฐ์ด ์ํธ ๋ฐฐ์ ์ธ์๋ ๋๊ธฐํ ์ฉ๋๋ก ์ธ๋งํฌ์ด๋ฅผ ์ฌ์ฉํ๊ธฐ๋ ํฉ๋๋ค.
์ด Semaphore์์๋ P ์ฐ์ฐ๊ณผ V ์ฐ์ฐ์ ์ด์ฉํด ์์์ ์ ๊ทผํฉ๋๋ค.
P()๋ ์๊ณ ๊ตฌ์ญ์ ์ง์ ํ๊ณ ์ ํ ๋ ํธ์ถํ๊ณ , V()๋ ์๊ณ ๊ตฌ์ญ์์ ๋์ฌ ๋ ํธ์ถํฉ๋๋ค.
P(s) {
while(S <= 0) {
do wait; // no operation
}
S--;
}
V(s) {
S++;
}
๐ P ์ฐ์ฐ
๊ณต์ ์์์ ์ป๊ธฐ ์ํด ์๊ณ ๊ตฌ์ญ์ ๋ค์ด๊ฐ๊ธฐ ์ entry section(์ง์ ๊ตฌ๊ฐ)์์ P ์ฐ์ฐ์ ํฉ๋๋ค.
์ด๋ ์ธ๋งํฌ์ด ๊ฐ์ ์ ๊ฒํ์ฌ ๋๊ตฐ๊ฐ ์ด ์์์ ์ฌ์ฉํ๋์ง ์ ์ ์์ต๋๋ค.
๋ง์ฝ ์ธ๋งํฌ์ด s > 0 ์ด๋ฉด, ํด๋น ์ค๋ ๋๊ฐ ์์์ ์ ๊ทผํ ์ ์๋ค๋ ์๋ฏธ์ ๋๋ค.
s๋ฅผ 1 ๊ฐ์์ํค๊ณ ์๊ณ ๊ตฌ์ญ์ ์ง์ ํฉ๋๋ค.
๋ฐ๋ฉด s <= 0์ด๋ฉด ๋ค๋ฅธ ์ค๋ ๋๊ฐ ์ด๋ฏธ ์๊ณ ๊ตฌ์ญ์์ ์์ ์ค์ด๋ผ๋ ์๋ฏธ์ด๋ฏ๋ก s๊ฐ ๋ค์ ์์๊ฐ ๋ ๋๊น์ง ๋๊ธฐํฉ๋๋ค.
์ด๋ s๋ ๋ฌด์์ ์๋ฏธํ ๊น์? ๋ฐ๋ก "ํ์ฌ ์๊ณ ๊ตฌ์ญ์ ์ง์ ๊ฐ๋ฅํ ์ค๋ ๋์ ์"์ ๋๋ค.
๐ V ์ฐ์ฐ
V์ฐ์ฐ์ ์ ์ ํ๊ณ ์๋ ๊ณต์ ์์์ ํ์ด์ฃผ๋ ๊ฒ์ ๋๋ค.
์๊ณ ๊ตฌ์ญ์์ ๋ฒ์ด๋ exit section์ ์ ์ด๋ค ๋ V ์ฐ์ฐ์ ์ํํฉ๋๋ค.
์ค๋ ๋๊ฐ ๊ณต์ ์์์ ๋ํ ์์ ์ ๋๋ด๋ฉด ์ธ๋งํฌ์ด s์ ๊ฐ์ด 1 ์ฆ๊ฐํฉ๋๋ค.
์ด๋ ๋๊ธฐํ๊ณ ์๋(sleep ์ํ์ด๋) ์ค๋ ๋๊ฐ ์์๋ค๋ฉด ์ ์์ ๊นจ์ด๋ ๊ณต์ ์์์ ์ ๊ทผํ๊ฒ ๋ฉ๋๋ค.
์ธ๋งํฌ์ด๋ ๋ฎคํ ์ค์ ๋ฌ๋ฆฌ ๋ฝ์ ๋ํ ์์ ๊ถ ๊ฐ๋ ์ด ์๋ ๊ณต์ ์์ ์ ๊ทผ ์ ์ด ๋๊ตฌ์ ๋๋ค.
์ธ๋งํฌ์ด๋ฅผ ์ฌ์ฉํ๋ ์ด๋ค ์ค๋ ๋๋ผ๋ V ์ฐ์ฐ์ผ๋ก ์ธ๋งํฌ์ด ๊ฐ์ ์ฆ๊ฐ์์ผ ์์์ ํด์ ํ ์ ์์ต๋๋ค.
V ์ฐ์ฐ์ “๊ณต์ ์์์ ์ฌ์ฉ์ด ๋๋ฌ์์ ์๋ฆด ์ฑ
์์ด ์๋ ์ค๋ ๋”๊ฐ ํธ์ถํฉ๋๋ค.
์ด ์ค๋ ๋๋ ๋ฐ๋์ P ์ฐ์ฐ์ ํ๋ ๊ฐ์ ์ค๋ ๋์ผ ํ์๋ ์์ต๋๋ค. (๋ฌผ๋ก ๊ฐ์๋ ๋ฉ๋๋ค.)
์๋ฅผ ๋ค์ด ์ด๋ฐ ๊ฒฝ์ฐ๊ฐ ์๋ค๊ณ ํฉ์๋ค. (์ฐธ๊ณ ๋ก ์ด ์์๋ ์ด์์ฒด์ ์์ ๋ง์ด ์์๋ก ๋๋ ์์ฐ์ - ์๋น์ ๋ฌธ์ ๋ฅผ ๋จ์ํํ ๋ฒ์ ์ ๋๋ค.)
- ๐ง๐พ ์์ฐ์ Producer: ์ํ์ ์์ฐํด ๋งํธ์ ๋ฉํํจ
- ๐งบ ์๋น์ Consumer: ๋งํธ์์ ์ํ์ ๊ตฌ์ ํจ
- ๋ฌธ์ : ์๋น์๋ ๋งํธ์ ์ํ์ด ์์ผ๋ฉด ๊ธฐ๋ค๋ ค์ผ ํจ
- โก๏ธ ์์ฐ์๊ฐ ๋งํธ์ ๋ฉํํ์ ๋ ์๋น์์๊ฒ "์ด์ ์ฌ!"ํ๊ณ ์ ํธ๋ฅผ ์ค์ผ ํจ
์ด๋ ์ธ๋งํฌ์ด๋ ํ์ฌ ๋งํธ์ ์ํ ์ฌ๊ณ ๊ฐ ๋ช ๊ฐ ์๋์ง๋ฅผ ๋ํ๋ด๋ ์ซ์ ์นด์ดํฐ์ ๋๋ค.
Semaphore items = new Semaphore(0); // ํ์ฌ ๋งํธ์ ์ํ์ด 0๊ฐ ์๋ค๊ณ ๊ฐ์
Thread producer = new Thread(() -> {
while (true) {
produceItem();
items.release(); // V ์ฐ์ฐ! ์ํ ํ๋ ์ถ๊ฐํ์ด!
}
});
Thread consumer = new Thread(() -> {
while (true) {
items.acquire(); // P ์ฐ์ฐ! ์ฌ๊ณ ๊ฐ ์์ผ๋ฉด ๊ธฐ๋ค๋ฆผ
consumeItem(); // ์ํ ๊ตฌ์
}
});
Producer๋ V ์ฐ์ฐ๋ง, Consumer๋ P ์ฐ์ฐ๋ง ํฉ๋๋ค.
์ด๋ก์จ ์์ฐ์๋ ์๋น์์๊ฒ ๋ฌผ๊ฑด์ ์ถ๊ฐํ๋ค๊ณ ์๋ฆฌ๊ณ , ์๋น์๋ ์์ฐ์์๊ฒ ๋ฌผ๊ฑด์ด ํ์ํ๋ค๊ณ ์๋ฆด ์ ์์ฃ .
์ธ๋งํฌ์ด๋ "๋๊ฐ" ์์์ ์ ๊ทผํ๋์ง๊ฐ ์ค์ํ ๊ฒ ์๋๋ผ
"๋ช ๊ฐ์ ์ค๋ ๋"๊ฐ ์์์ ์ ๊ทผํ๋์ง๊ฐ ์ค์ํ๊ธฐ ๋๋ฌธ์ ๋๊ตฌ๋ ๋ฝ์ ํด์ ํ ์ ์์ต๋๋ค.
์ ๋ฆฌํ์๋ฉด,
๋ฎคํ ์ค์์๋ ํ๋์ ์์์ ๋์์ ํ๋์ ์ค๋ ๋๋ง์ด ์ ๊ทผํ ์ ์์๊ณ , ๋ฝ์ ์ค์ ํ ์ค๋ ๋๋ง ๋ฝ์ ํด์ ํ ์ ์์ต๋๋ค.
(๋๊ธฐํ ๋์์ด ํ๋)
์ธ๋งํฌ์ด์์๋ ๋ฏธ๋ฆฌ ์ง์ ํ ์ต๋ N๊ฐ์ ์ค๋ ๋๊ฐ ํ๋์ ์์์ ๋์ ์ ๊ทผํ ์ ์์ต๋๋ค. ๋๊ตฌ๋ ๋ฝ์ ํด์ ํ ์ ์์ต๋๋ค.
(๋๊ธฐํ ๋์์ด ํ๋ ์ด์)
๐ก ์์ฝ
๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์๋
์ฌ๋ฌ ์ค๋ ๋๊ฐ ๊ณต์ ์์์ ๋์์ ์ ๊ทผํ๋ฉด์
๋ฐ์ดํฐ ๋ถ์ผ์น๋ ์๊ธฐ์น ์์ ๋์ ๋ฌธ์ ๊ฐ ์ผ์ด๋ ์ ์์ต๋๋ค.
์ด๋ฅผ ๋ฐฉ์งํ๋ ค๋ฉด ๋์์ ์คํ๋๋ ์ค๋ ๋ ๊ฐ ์์ ์ ๊ทผ์ ์กฐ์จํด์ผ ํ๋ฉฐ,
์ด๋ฅผ ์ํด ๋ฎคํ
์ค(Mutex), ์ธ๋งํฌ์ด(Semaphore)์ ๊ฐ์ ๋๊ธฐํ ๋๊ตฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ๐งต ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ(Multi-Thread): ๋์์ ์ฌ๋ฌ ์์ ์ด ๊ฐ๋ฅํ์ง๋ง, ๊ณต์ ์์ ์ถฉ๋ ์ํ์ด ์์
- โ ๏ธ ๊ฒฝ์ ์ํ(Race Condition): ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ๊ฐ์ ์์์ ์ ๊ทผํ ๋ ์คํ ์์์ ๋ฐ๋ผ ์ค๋ฅ ๋ฐ์
- โ ์ํธ ๋ฐฐ์ (Mutual Exclusion): ์ด๋ฏธ ์๊ณ ๊ตฌ์ญ(critical section)์์ ์์ ์ค์ธ ์ค๋ ๋๊ฐ ์๋ค๋ฉด, ๋ค๋ฅธ ์ค๋ ๋๋ ์ ๊ทผ ๋ถ๊ฐ
- ๐ ๋ฎคํ ์ค (Mutex): ํ ๋ฒ์ ํ๋๋ง ์ ๊ทผ ๊ฐ๋ฅ, ๋ฝ ์์ ์๋ง ํด์ ๊ฐ๋ฅ
- ๐ข ์ธ๋งํฌ์ด (Semaphore): ๋์์ ์ฌ๋ฌ ์ค๋ ๋ ์ ๊ทผ ๊ฐ๋ฅ, ์์ ์ ๊ด๊ณ ์์ด ํด์ ๊ฐ๋ฅ
์ฐธ๊ณ ์๋ฃ
- ๋ฉํฐ ํ๋ก์ธ์ค vs ๋ฉํฐ ์ค๋ ๋ ๋น๊ต ์์ ์ด์ ๋ฆฌ
- ์ค๋ ๋(Thread), ๋ฉํฐ์ค๋ ๋(Multi-Thread)!
- ๊ฒฝ์ ์ํ(Race Condition)
- [Thread] ๋ฎคํ ์ค, ์ธ๋งํฌ์ด, ๋ชจ๋ํฐ์ ์ค๋ ๋ ๋๊ธฐํ์ ๊ตฌํ ์์
- ๊ด์ด๋ํ๊ต ์์คํ ํ๋ก๊ทธ๋๋ฐ ๊ต๊ณผ๋ชฉ ๊ฐ์์๋ฃ
- + ํ์ ํ์์ ๋์ ๊ธ