์กฐ๊ฑด๋ณ์๋? ๋๊ธฐํ ๋ฉ์ปค๋์ฆ ์ค ์ธ๋งํฌ์ด์ ๋ฎคํ ์ค, ๋ฝ์ ์ต์ํ๋ฐ ์ฌ๊ธฐ์ ์ฝ๊ฐ ๋ ์ฌํํ๋ค๋ฉด ๋์ฌ ์ ์๋ ๊ฒ ์กฐ๊ฑด๋ณ์๋ค. ์์ฑ์-์๋น์ ๋ฌธ์ ์ ๊ด๋ จํด ์ฌ์ฉ๋ ์ ์๋ค.
1. Monitor
๋์์ฑ ํ๋ก๊ทธ๋๋ฐ์์, ๋ชจ๋ํฐ๋ ์ค๋ ๋๊ฐ ๊ณต์ ๊ฐ์ ์ ์ํ์ ๋์์ ์ผ๋ก ์ ๊ทผํ๋ ๊ฒ์ ๋ง๊ณ ํด๋น ์ํ๊ฐ ๋ณ๊ฒฝ๋์ด ์กฐ๊ฑด์ด ์ถฉ์กฑ๋ ๋๊น์ง ๋๊ธฐํ ์ ์๋๋ก ํ๋ ๋๊ธฐํ ๊ตฌ์กฐ์ด๋ค. ์ฆ, ์ ๊ทผ ๊ฐ๋ฅํ ์ค๋ ๋์ ์๋ฅผ ์ ํํ๋ ์ธ๋งํฌ์ด๋ ์ผ๋ฐ ๋ฎคํ ์ค์ ๋ค๋ฅด๊ฒ, ๋ชจ๋ํฐ๋ ํน์ ์กฐ๊ฑด์ ์ถฉ์กฑ์ ๊ธฐ์ค์ผ๋ก ๊ณต์ ์์์ ๋ํ ๋ ์ ์ ์ธ ์ก์ธ์ค๋ฅผ ์ ๊ณตํ๋ค. (ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผํ ์ ์๋ค.) ์ผ๋ฐ์ ์ผ๋ก ๋ฝ๊ณผ ํ๋ ์ด์์ ์กฐ๊ฑด ๋ณ์๋ก ๊ตฌ์ฑ๋๋ค.
2. Conditional Variable
์กฐ๊ฑด ๋ณ์๋ ํด๋น ์กฐ๊ฑด์ ์ถฉ์กฑ์ ๋๊ธฐํ๊ณ ์๋ ๋๊ธฐ์ด๋ก ๊ตฌ์ฑ๋๋ค. ์กฐ๊ฑด ๋ณ์๋ ํด๋น ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋ ๋ช ์์ ์ผ๋ก ์๊ทธ๋์ ๋ณด๋ด ๋๊ธฐ์ด์ ์๋ ์ค๋ ๋ ์ค ์ผ๋ถ ๋๋ ์ ๋ถ๋ฅผ wakeํ๋ค.
wait(condvar, lock)
๋ง์ฝ ์กฐ๊ฑด๋ณ์๊ฐ ์ฐธ์ด ์๋๋ผ๋ฉด, ๋ชจ๋ํฐ๋ฅผ ํ๋ํ ์ ์์ผ๋ฏ๋ก wait ์ฐ์ฐ์ ์คํํ๊ฒ ๋๋ค. ์ค๋ ๋์ ์ํ๊ฐ Running์์ Block๋ก ๋ณ๊ฒฝ๋๊ณ , condvar์ ๋๊ธฐ์ด๋ก ์ด๋๋์ด ๋ธ๋ฝ๋๋ค.
signal(condvar)
์กฐ๊ฑด๋ณ์๊ฐ ์ฐธ์ด ๋๋ฉด ๋ชจ๋ํฐ๋ฅผ ํ๋ํ ์ค๋ ๋์ ์ํด ํธ์ถ๋๋ค. ๋๊ธฐ์ด์์ ํ๋์ ์ค๋ ๋๋ฅผ ์ ํํด ๊นจ์ฐ๋ ์ฐ์ฐ์ผ๋ก, ๊ตฌ์ฒด์ ์ผ๋ก๋ ์ํ๋ฅผ Block์์ Ready๋ก ๋ณ๊ฒฝํ ํ ์ค์ผ์ค๋ง์ ์ํ ๋๊ธฐ ํ๋ก ์ด๋์ํจ๋ค. ์ด๋ ์ค๋ ๋๋ฅผ ๊นจ์ธ์ง๋ ๊ตฌํ ์ ์ฑ ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ฐ, FIFO๋ฅผ ์ธ์๋ ์๊ณ ์ฐ์ ์์ ์ค์ผ์ค๋ง์์๋ ์ฐ์ ์์ ์์ผ์๋ ์๋ค.
broadcast(condvar)
signal๊ณผ ์ ์ฌํ์ง๋ง, ํด๋น ์กฐ๊ฑด๋ณ์์ ๋ชจ๋ ์ค๋ ๋๋ฅผ ๊นจ์ด๋ค๋ ์ ์ด ๋ค๋ฅด๋ค. ๊นจ์ด๋ ์ค๋ ๋๋ ๋๊ธฐ์ด์์ ๋์จ ์์ผ๋ก ๋ฝ์ ํ๋์ ์๋ํ๊ณ , ๋๋จธ์ง ์ค๋ ๋๋ ํด๋น ๋ฝ์ ๋๊ธฐ์ด๋ก ๋ค์ด๊ฐ๋ค.
3. Producer-Consumer Problem
์์ ํ์ ์์ฐ์, ์๋น์ ์ค๋ ๋๊ฐ ์๋ค๊ณ ํ์. ์์ฐ์ ์ค๋ ๋๋ ํ์ ์์ ์ ์ถ๊ฐํ๊ณ ์๋น์ ์ค๋ ๋๋ ํ์์ ์์ ์ ๊บผ๋ธ๋ค. ์ด ํ๋ฅผ thread safeํ๋๋ก ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น?
์ผ๋จ ๋ง์ฝ ํ์ ๋ํ ์ํธ ๋ฐฐ์ ๊ฐ ์๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น? ํ์ ์ ๊ทผํ ๋์ ํ์ ์ํ๊ฐ ์ผ๊ด๋์ง ์์ ์ ์๋ค. ์์ฐ ํน์ ์๋น ์ ๊ทผ์ด ์์์ ์ผ๋ก ์ด๋ฃจ์ด์ง์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ฌํ ์ํ๋ฅผ race condition์ด๋ผ๊ณ ํ๋ค.
๊ทธ๋์ ํ์ ๋ฝ์ ๊ฑธ์ด ์ํธ ๋ฐฐ์ ๋ฅผ ๊ตฌํํ๋ค. ํ์ง๋ง ํ์ ๋ํ ์ ๊ทผ์ ์ํธ ๋ฐฐ์ ํ๋ ๊ฒ์ผ๋ก๋ ๋ถ์กฑํ๋ค. ์ฌ๋ฌ ์์ฐ์ ์ค๋ ๋๊ฐ ํ๊ฐ ๊ฐ๋ ์ฐผ์์๋ ๋ถ๊ตฌํ๊ณ ๋์๊ฐ๋ฉด์ ํ์ ์ฝ์ ์ ์๋ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ฆ, ๋จ์ง ์ ๊ทผ ์ ์ด๊ฐ ์๋๋ผ ํ์ ์ํ (is_full, is_empty)๋ฅผ ๋ณด์์ผ ํ๋ค. ํ์ ์ํ๋ฅผ ์ฒดํฌํ๋ฉด์ busy-waiting ๋ฐฉ์์ผ๋ก ์ค๋ ๋๋ฅผ ๋๊ธฐ์ํค๋ ์คํ๋ฝ์ ์ฌ์ฉํ ์๋ ์์ง๋ง, ๋ช ์์ ์ธ ๋๊ธฐ์ด์ ๋๊ณ blocking ๋ฐฉ์์ ์ฌ์ฉํ๋ ๊ฒ CPU๋ญ๋น๊ฐ ์๋ค๋ ์ ์์ ๋ ์ข๋ค. ๋ฐ๋ผ์ ์ด๋ฅผ ์ํด ์กฐ๊ฑด๋ณ์๊ฐ ์ฌ์ฉ๋ ์ ์๋ค.
// pseudo
bool is_full, is_empt;
cv cv_full; // full ์ธ ๊ฒฝ์ฐ ์์ฐ์ ์ค๋ ๋๊ฐ ๋๊ธฐํจ
cv cv_empt; // empty์ธ ๊ฒฝ์ฐ ์๋น์ ์ค๋ ๋๊ฐ ๋๊ธฐํจ
queue taskq;
void produce(Task t) {
acquire(taskq.lock);
while(taskq.is_full) {
wait(taskq.lock, cv_full);
}
taskq.enqueue(t);
signal(cv_empt); // ๋๊ธฐํ๋ ์๋น์ ์ค๋ ๋ ๊นจ์
release(taskq.lock);
}
Task consume() {
acquire(taskq.lock);
while(taskq.is_empty) {
wait(taskq.lock, cv_empt);
}
Task t = taskq.dequeue();
signal(cv_full); // ๋๊ธฐํ๋ ์์ฐ์ ์ค๋ ๋ ๊นจ์
release(taskq.lock);
return t;
}
What's more?
Spurious wakeup
์ค๋ ๋๊ฐ ์ ํธ๋ฅผ ๋ฐ์ง ์์๋๋ฐ ๋๊ธฐ์์ ๊นจ์ด๋๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. (์ ๊ทธ๋ฐ๊ฐ?) ์ด๋ฐ ํ์์ด ์์ด์ signal
ํจ์ ์ข
๋ฃ ํ์ ์ค์ ์กฐ๊ฑด ๋ณ์๊ฐ ๋ณ๊ฒฝ๋ ๊ฒ ๋ง๋์ง ํ ๋ฒ ๋ ๊ฒ์ฆํ๋ ์ฝ๋๋ฅผ ์ฌ์ ์ ์๋ค. cv_full
์กฐ๊ฑด๋ณ์์ ๋ํ signal
ํจ์ ์คํ ํ์ !taskq.is_full
์ด true
์ธ์ง ํ๋ฒ ๋ ์ฒดํฌํ๊ณ , ์๋ ๊ฒฝ์ฐ ๋ค์ wait
ํ๋ ์์ด๋ค.
'DevLog ๐จ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[DevLog][PintOS] 3์ฃผ๊ฐ์ ํํ ์ค ํ๊ณ (1) | 2023.10.24 |
---|---|
[DevLog][PintOS] PRJ3 Virtual Memory/Memory Mapped Files to Copy-on-write (1) | 2023.10.24 |
[DevLog][PintOS] PRJ3 Virtual Memory/Memory Management to Stack Growth (2) | 2023.10.17 |
[DevLog][PintOS] PRJ2 User Program/Out of Memory Test (0) | 2023.10.10 |
[DevLog][PintOS] PRJ1 Threads/PintOS ์ค๋ ๋๋ ์ด๋ป๊ฒ ๋์๊ฐ๊น? (0) | 2023.10.03 |