์ธ๋งํฌ์ด(Semaphores)๋?
์ง๊ธ๊น์ง Critical Section Ploblem์ ์ํํธ์จ์ด/ํ๋์จ์ด์ ์ผ๋ก ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์๋ดค๋ค. ์ํํธ์จ์ด์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก๋ ์ธ ๊ฐ์ง ์๋ฃจ์ ์ด ์์๊ณ , ํ๋์จ์ด์ ์ธ ๋ฐฉ๋ฒ์๋ Testset ์ธ์คํธ๋ญ์ ์ ์ฌ์ฉํ๋ค.
์กฐ๊ธ ๋ ๋์ ๋ฐฉ์์ ํ๋์จ์ด์ ์ผ๋ก ํด๊ฒฐํ๋ ๊ฒ์ด๋ผ ํ์๋๋ฐ, Testset ์ญ์๋ Busy Wating์ ํด์ผํ๋ ํฐ ๋จ์ ์ด ์๋ค.
์ธ๋งํฌ์ด๋ Busy Wating์ ํด๊ฒฐํ๋ ํจ์จ์ ์ธ ๋ฐฉ๋ฒ์ ์ ์ํ๋ค. ์ธ๋งํฌ์ด ์์ฒด๋ง์ผ๋ก๋ Int ๊ฐ์ ์ ์ฅํ ๋ฟ์ธ ๊ตฌ์กฐ์ฒด์ผ ๋ฟ์ด์ง๋ง, _semWait (s)_์ _semSignal (s)_์ ํตํด์ ์์ฝ๊ฒ Critical Section Ploblem์ ํด๊ฒฐํ๋ค.
- semWait (s)
- semiphore์ ๊ฐ์ 1 ๊ฐ์ ์ํจ๋ค.
- ์ด์์ฒด์ ์ ๋ฐ๋ผ P(s), Wait(s), down(s)์ผ๋ก๋ ๋ถ๋ฆฐ๋ค.
- semSignal (s)
- ์ด์์ฒด์ ์ ๋ฐ๋ผ called V(s), Signal (s), sem_post(s)์ผ๋ก๋ ๋ถ๋ฆฐ๋ค.
๊ฐ ํจ์๋ค์ ํ๋์จ์ด์ ์ง์์ ๋ฐ์ atomic ํ๊ฒ ๋์ํ๋ค.
Testset์ ํ๋์ ํ๋ก์ธ์ค๊ฐ ๊ณต์ ์์์ ๋ํด ์ ์ ํ๊ณ ์๋ค๋ฉด ๋ค๋ฅธ ํ๋ก์ธ์ค๋ _while_๋ฌธ์ ํตํด ์๋ฏธ ์๋ time slice๋ฅผ ์๋ชจํ๋ค. ๊ทธ๋ฌ๋ ์ธ๋งํฌ์ด๋ ๋ค๋ฅด๋ค. ์ธ๋งํฌ์ด๋ฅผ ํตํด ํ๋ก์ธ์ค๋ ์ด๋ ํ ํ๋ก์ธ์ค๊ฐ ๊ณต์ ์์์ ์ ์ ํ๊ณ ์๋ค๋ ์ฌ์ค์ ์๋ค. ํด๋น ์ฌ์ค์ ๋ฐํ์ผ๋ก ํ๋ก์ธ์ค๋ ๋๊ธฐ ํ(Block Queue)์ ๋ค์ด๊ฐ ์ฐ์ ์์์ ๋ฐ๋ผ ๊ธฐ๋ค๋ฆฐ๋ค. _semWait_๊ฐ ๋ฐ๋ก ์ด๋ ๊ฒ ๋๊ธฐ ํ์ ๋ค์ด๊ฐ๊ฑฐ๋ ์์์ ์ฐจ์งํ๋ ๊ฒ ์ค ํ๋๋ฅผ ๊ฒฐ์ ํ๋ค.
๊ณต์ ์์์ ์ ์ ํ๊ณ ์๋ ํ๋ก์ธ์ค๊ฐ ํด๋น ์์์ ๋ค ์ฌ์ฉํ๋ค๊ณ ํด๋ณด์. ์ด๋ _semSignal_์ ์ฌ์ฉํ๋ค. ์ด ํจ์๋ ๋๊ธฐ ํ์ ๋ง์ฝ ํ๋ก์ธ์ค๊ฐ ์๋ค๋ฉด, ์ฐ์ ์์์ ํด๋น๋๋ ํ๋ก์ธ์ค๋ฅผ Block ์ํ์์ Ready Queue๋ก ์ด๋์ํจ๋ค.
Ready Queue๋ก ๋ค์ด๊ฐ ํ๋ก์ธ์ค๋ _semWait_์์ Block ๋ ์ํ์์ ํ๋ ค๋๊ธฐ ๋๋ฌธ์ Critical Section ๋ด์ ์์์ ๊ฐ์ง๋ ๊ฒ์ด ๊ฐ๋ฅํด์ง๋ค.
์ฝ๋๋ฅผ ํตํด ์ดํด๋ณด์.
semaphore
struct semaphore {
int count;
queueType queue;
}
semWait(semaphore s)
void semWait (semaphore s) {
s.count--;
if (s.count < 0) {
/* ํ๋ก์ธ์ค๋ฅผ ๋๊ธฐ ํ(s.queue)๋ก ์ง์ด๋ฃ๋๋ค. */
/* ํ๋ก์ธ์ค Block */
}
}
semSignal (semaphore s)
void semSignal (semaphore s) {
s.count++;
if (s.count <= 0) {
/* ๋๊ธฐ ํ(s.queue)๋ก๋ถํฐ ํ๋ก์ธ์ค ์ ๊ฑฐ */
/* ํ๋ก์ธ์ค๋ฅผ Ready Queue๋ก ๋ฃ๋๋ค. */
}
}
๋๊ธฐ ํ๊ฐ ์ semaphore ๊ตฌ์กฐ์ฒด ์์ ์์๊น? ์ด์ ์ ๋ดค๋ ํ๋ก์ธ์ค ์ํ๋๋ฅผ ๋ ์ฌ๋ ค๋ณด์. ๋๊ธฐ ํ๋ ํ๋๋ก๋ง ์ด๋ฃจ์ด์ง ๊ฒ ์๋๋ค. ์ฌ๋ฌ ์ด๋ฒคํธ๋ค์ ๋ํด ๊ฐ๊ธฐ ๋ค๋ฅธ ๋๊ธฐ ํ๊ฐ ์๋ค.
s.queue ๋ํ semaphore์์ ๋ฐ์ํ๋ ์ด๋ฒคํธ์ ๋ํ ๋๊ธฐ ํ์ผ ๋ฟ์ด๋ค.
์ธ๋งํฌ์ด์์ ์์ฃผ ์ฌ์ฉํ๋ ํจํด
์ฝ๋๋ง์ผ๋ก ๋ณธ๋ค๋ฉด ๋์์ ์์ํ๊ธฐ ์ด๋ ต๋ค. ์ค์ ๋ก ์ธ๋งํฌ์ด๋ ์ด๊ธฐ์ ์ ์ฅ๋๋ ๊ฐ์ ๋ฐ๋ผ ๋ ผ๋ฆฌ์ ์ธ ์๋ฏธ๊ฐ ๋ฌ๋ผ์ง๋ค. ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ๋ถํฐ ์์๋ณด์.
1. ๊ฐ๋จํ๊ฒ Mutual Exclusion์ ๋ณด์ฅํ๋ ํจํด
์ ์ผ ๋ง์ด ์ฌ์ฉํ๋ ํจํด์ด๋ค. semaphore์ ์ด๊ธฐ๊ฐ 1์ ์ ์ฅํ๋ค.
const int n = /* ํ๋ก์ธ์ค ๊ฐฏ์ */
semaphore s = 1;
void P(int i) {
while (true) {
semWait (s);
/* critical section */
semSignal (s);
/* remainder */
}
}
void main() {
parbegin(P(1), P(2), ... , P(n));
}
_semWait_์ 1 ๊ฐ์ด ์ ๋ฌ๋๋ค๋ฉด, _count_๊ฐ ํ๋ ์ค์ด๋ค์ด ์ธ๋งํฌ์ด๋ 0์ ๊ฐ์ ๊ฐ์ง๋ค. Context Switch ๋ ํ๋ก์ธ์ค๋ critical section์ ์ ๊ทผํ ๋ _count_๊ฐ 0 ๋ฏธ๋ง์ ๊ฐ์ ๊ฐ์ง๋ค. ๋ฐ๋ผ์ Context Switch๋ ํ๋ก์ธ์ค๋ ๋๊ธฐ ํ์ ๋ค์ด๊ฐ๋ฉฐ Block ์ํ๋ก ์ด๋ํ๋ค.
๋ค์ Context Switch ๋์ด ๊ธฐ์กด ํ๋ก์ธ์ค๋ก ๋์์๋ณด์. critical section์ ๋ชจ๋ ์์ ์ด ๋๋๊ณ , _semSignal_์ด ํธ์ถ๋ ์ํฉ์ด๋ค. count๋ ๋ค์ ํ๋ ์ฆ๊ฐํ๋ค.
๋ง์ฝ ์ด ํ๋ก์ธ์ค๊ฐ critical section์ ์๋ ๋์ ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ์๋ฌด๋ _semWait_์ ํธ์ถํ์ง ์์๋ค๋ฉด semaphore๋ 1์ด๋ค. ์ด๋ฐ ์ํ์์ Context Switch๋์ด ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ Critical Section์ ์ ๊ทผํด๋ ์๋ฌด๋ฐ ๋ฌธ์ ๊ฐ ์๋ค.
ํ๋์ ํ๋ก์ธ์ค๊ฐ critical section์ ์๋ ๋์ ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ _semWait_์ ํธ์ถํ๋ค๊ณ ํด๋ณด์. ํธ์ถํ ํ๋ก์ธ์ค๋ semaphore๋ฅผ ํ๋ ๋นผ์ด -1์ด ๋๊ณ , Block ์ํ๋ก ์ด๋ํ๋ค. ๊ธฐ์กด์ critical section์ ์๋ ํ๋ก์ธ์ค๊ฐ ๋๋ฌ๋ค. ๊ทธ๋ฌ๋ฉด _semSignal_๋ก ์ธํด semaphore๋ 0์ด ๋์ง๋ง, ๋๊ธฐ ํ์ ํ๋ก์ธ์ค๊ฐ ์กด์ฌํด ์กฐ๊ฑด๋ฌธ ์์ผ๋ก ์ง์ ํ๋ค.
์กฐ๊ฑด๋ฌธ์ผ๋ก ์ธํด ๋๊ธฐ ํ์ ์กด์ฌํ๋ ํ๋ก์ธ์ค๋ Ready Queue๋ก ์ด๋ํ๋ค. Ready Queue์ ์๋ ํ๋ก์ธ์ค๋ ์ด์ Critical Section์ผ๋ก ์ด๋์ด ๊ฐ๋ฅํ๋ค.
2. ํ๋ก์ธ์ค ๊ฐ ์ฐ์ ์์๋ฅผ ๋ณด์ฅํ๋ ํจํด
ํ๋์ ํ๋ก์ธ์ค๊ฐ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ณด๋ค ๋จผ์ ์คํํด์ผ ํ๋ค๋ฉด semaphore๋ฅผ 0์ผ๋ก ๋์. ๋ํ ์ฝ๋์ ์์น๋ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๋์.
์กฐ๊ฑด๋ง ๋ง์กฑ์ํจ๋ค๋ฉด ์ด๋ ํ ์ํฉ์ด๋ , Pi๊ฐ Pk๋ณด๋ค ๋จผ์ ๋์ํ๋ค.
1. Pk๊ฐ ๋จผ์ ์คํ๋ ๊ฒฝ์ฐ
_semWait_์ผ๋ก ์ธํด semaphore๋ -1์ด๋ค. ๋ฐ๋ผ์ Pk๋ Block ๋๋ค. Pi๋ ๋ฐ๋ก _semWait_์ด ์๋ค. ๋ฐ๋ผ์ ์ฝ๋๋ฅผ ์งํํ๋ค๊ฐ _semSignal_๋ฅผ ์ด๋ด ๋ง๋๋ค. _semSignal_๋ก ์ธํด semaphore๋ 0์ด ๋๊ณ , Pk๋ Ready Queue๋ก ๋น ์ ธ๋๊ฐ ์ฝ๋ ์คํ์ด ๊ฐ๋ฅํด์ง๋ค.
2. Pi๊ฐ ๋จผ์ ์คํ๋ ๊ฒฝ์ฐ
Pi๋ _semWait_์ด ์์ผ๋ _semSignal(flag)_๋ฅผ ๋ง๋ ๋๊น์ง ํธํ๊ฒ ์คํํ๋ค. ํน์ฌ๋ Pk๋ก ๋ฐ๋๋๋ผ๋ 1. ์ ๊ณผ์ ์ ํตํด Pi๊ฐ ๋จผ์ ์คํ๋จ์ด ๋ณด์ฅ๋๋ค. _semSignal(flag)_๋ฅผ ๋จผ์ ๋ง๋๋ฉด semaphore๋ 1์ด ๋๋ฉฐ Pk๋ก ๋ฐ๋์ด๋ Pk๋ ๋๊ธฐํ๋ก ๋ค์ด๊ฐ์ง ์๋๋ค.
โป Producer/Consumer ๋ฌธ์ ํด๊ฒฐํ๊ธฐ
์์ Race Condition์ด ๋ฐ์ํ๋ Producer/Consumer ๋ฌธ์ ๋ฅผ ์ธ๋ง ํฌ์ด๋ฅผ ํตํด ํด๊ฒฐํด ๋ณด์.
Semaphore
semaphore counter = 0;
semaphore empty = BUFFER_SIZE;
semaphore mut_ex = 1;
Producer
while (true) {
produce();
semWait(empty);
semWait(mut_ex);
append();
semSignal(mut_ex);
semSignal(counter);
}
Consumer
while (true) {
semWait(counter);
semWait(mut_ex);
take();
semSignal(mut_ex);
semSignal(empty);
consume();
}
_mut ex_๋ 1 ํจํด์ ์ ์ฉ์ํจ ๊ฒ์ด๋ค. ๊ฐ ์์ ์ ์ํํ๋๋ฐ Race Condition์ด ์ผ์ด๋์ง ์๋๋ก ํด์ค๋ค.
_counter_๋ Producer๊ฐ ์ฐ์ ์ ์ผ๋ก ์คํํ๋๋ก ํ๋ค.
_empty_๋ BUFFER SIZE๋งํผ ์ฑ์์ ธ ์๋๋ฐ, ๋ฒํผ๋ณด๋ค ๋ ๋ง์ Produce()๊ฐ ์ผ์ด๋์ง ์๊ฒ ํ๋ค.
3. Readers/Writers Problem์ ํด๊ฒฐํ๋ ํจํด
์ฌ๋ฌ ํ๋ก์ธ์ค๊ฐ ์ฝ๋ ๊ฒ์ ๊ฐ๋ฅํ์ง๋ง, ์ฝ๋ ํ๋ก์ธ์ค๊ฐ ์ด๋ ํ๋๋ผ๋ ์๋ค๋ฉด ์์ ์ ํด์๋ ์๋๋ค. ์ธ๋งํฌ์ด๋ฅผ ์ฌ์ฉํ๋ค๋ฉด, ์ด๋ฅผ ๋ณด์ฅํ๋ ํจํด์ ์์ฝ๊ฒ ๋ง๋๋ ๊ฒ ๊ฐ๋ฅํ๋ค.
Writer
void writer() {
while (true) {
semWait(wsem);
WRITEUNIT();
semSignal(wsem);
}
}
Reader
void reader() {
while (true) {
semWait(rsem);
readcount++;
if (readcount == 1) semWait (wsem);
semSignal(rsem);
READUNIT();
semWait (rsem);
readcount--;
if (readcount == 0) semSignal(wsem);
semSignal (rsem);
}
}
_rsem_๊ณผ _wsem_์ ๊ฐ๊ฐ reader์ writer์ ๋ํ ์ธ๋งํฌ์ด ๋ณ์ ๊ฐ์ด๋ค. ์ด ๊ฐ๋ค์ ๊ฐ๊ฐ 1๋ก ์ด๊ธฐํํ๋ค.
๋จผ์ _semWait(rsem)_๊ณผ _semSignal(rsem)_์ด ์ฌ์ฉ๋๋๋ฐ, ์ด๋ _readcount_๋ฅผ ์ฆ๊ฐ์ํค๋ ์ผ์ด ๋ค๋ฅธ reader๋ค๊ณผ ๊ฒฝ์๊ด๊ณ๊ฐ ์ผ์ด๋๋ฉด ์ ๋๊ธฐ ๋๋ฌธ์ด๋ค.
_readcount_๊ฐ 1์ด๋ผ๋ ๊ฒ์ reader ํ๋๊ฐ ์ฒ์ ๋ค์ด์๋ค๋ ๋ป์ด๊ณ , writer๊ฐ ๋ฏธ๋ฆฌ ๋ค์ด๊ฐ ์๋ ๊ฐ๋ฅ์ฑ์ ๊ณ ๋ คํด์ผ ํ๋ค. writer๊ฐ ๋ฏธ๋ฆฌ ๋ค์ด๊ฐ ์๋ค๋ฉด reader๋ writer๊ฐ ๋์ฌ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํ๋ฏ๋ก _semWait(wsem)_์ ํ๋ค. ๋ฐ๋๋ก writer๊ฐ ๋ค์ด๊ฐ ์์ง ์๋ค๋ฉด reader๊ฐ ๋จผ์ _semWait(wsem)_์ ํธ์ถํ์ผ๋ฏ๋ก, writer๋ ๋ค์ด๊ฐ ์ ์๋ค.
reader๊ฐ ์ฝ๋ ๋์ ์์ ํ ์ ์๊ณ , writer๊ฐ ์์ ํ๋ ๋์ reader๋ ์ฝ์ ์ ์๋ ๊ฒ์ด๋ค.
์ฌ๊ธฐ๊น์ง์ ๊ณผ์ ์ ํต๊ณผํ๋ค๋ฉด, read์์ ์ด ์ผ์ด๋๋ ์ข๋ค. READUNIT() ํจ์๋ฅผ ํธ์ถํด ์ฃผ์.
์ด์ ๋ชจ๋ read์์ ์ด ๋๋ฌ๋ค. ๊ทธ๋ฌ๋ฉด _readcount_๋ ํ๋ ์ค์ด๋ค์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ง์ฐฌ๊ฐ์ง๋ก 1 ํจํด์ ์ ์ฉ์์ผ ์ฃผ์. _readcount_๊ฐ 0์ธ ์กฐ๊ฑด์ ๋ ์ด์ ์๊ธฐ ์์ ํ๋ก์ธ์ค ๋ค์ ๋ค๋ฅธ read ํ๋ก์ธ์ค๊ฐ ์๋ ์ํ๋ค. ์์ _semWait(wsem)_์ผ๋ก reader๊ฐ ์ฝ๋ ๋์ ์์ ํ์ง ์๋๋ก ์ค์ ํด ์ฃผ์๊ธฐ ๋๋ฌธ์ writer๊ฐ ๋ค์ ์์ ํ ์ ์๋๋ก ํ์ด์ฃผ์ด์ผ ํ๋ค. ์ด๋ฐ ์ญํ ์ ํด์ฃผ๋ ๊ฒ _semSignal(wsem)_์ด๋ค.
Binary Semaphore, Lock
์ธ๋งํฌ์ด ๊ฐ์ 0๊ณผ 1๋ง ๊ฐ์ง๋ ์ธ๋งํฌ์ด๋ฅผ Binary Semaphore(= mutex)๋ผ๊ณ ํ๋ค.
์ด๋ฏธ critical section์ ์ด๋ ํ๋ก์ธ์ค๊ฐ ๋ค์ด๊ฐ ์๋ค๋ฉด, ์ด๋ค ํ๋ก์ธ์ค๋ ๋ค์ด๊ฐ ์ ์๋ค.
๊ธฐ์กด์ ๋ฐฐ์ด ๊ฒ๊ณผ ๋ค๋ฅธ ์ ์ ready queue์ ๊ฐ๋ ์ผ๋ก ๋๊ธฐํ๋ ํ๋ก์ธ์ค ๊ฐ์ ์ฐ์ ์์๊ฐ ์ ํด์ง์ง ์๋๋ค. ๋ฐ๋ผ์ ์ด๋ก ์ bounded wating์ด ์ ์ฉ๋์ง ์๋๋ค.
Lock๋ ๊ฒฐ๊ตญ Binary Semaphore๋ฅผ ๋ํ๋ธ๋ค. ์ด๋ฆ๋ง ๋ค๋ฅผ ๋ฟ์ด์ง ์ค์ ๋ก ๋์์ ๊ฐ๋ค. Linux์์๋ lock์ ์ฒ๋ฆฌํ๋ Thread Library๊ฐ ์๋ค. phread mutex unlock๊ณผ pthread mutex lock์ด ์์ผ๋ฉฐ bounded wating์ ๋ณด์ฅํ๋ค.
Monitors
ํ๋ก๊ทธ๋๋จธ๋ค์ด ๋ณด๋ค ์ฝ๊ฒ ๋๊ธฐํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๊ณ ์์ค์ ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ด๋ค.
'๐ Knowledge > ์ด์์ฒด์ (OS)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์ด์์ฒด์ ] File๊ณผ Device File (0) | 2024.04.14 |
---|---|
[์ด์์ฒด์ ] DeadLock๊ณผ DeadLock ์๋ฐฉ๋ฒ (2) | 2024.04.13 |
[์ด์์ฒด์ ] Testset ์ธ์คํธ๋ญ์ (0) | 2024.04.06 |
[์ด์์ฒด์ ] ํ๋ก์ธ์ค ๋๊ธฐํ, Race Condition, Critical Section (0) | 2024.03.31 |
[์ด์์ฒด์ ] ์ค๋ ๋(Thread)์ ๋ฉํฐ ์ค๋ ๋(MultiThread)๋ ๋ฌด์์ผ๊น (0) | 2024.03.24 |