ํ๋ก์ธ์ค ๋๊ธฐํ ๋๊ตฌ์ ๋ํด ์์๋ณธ๋ค.
Semaphore(์ธ๋งํฌ)
Semaphoresms ๊น๋ฐ์ด๋ผ๋ ๋ค๋๋๋ ๋จ์ด์ด๋ค. ์๋ ์๋ ๊ธฐ์ฐป๊ธธ์์ ๊ณต์ ํ๋ ๊ธธ์ด ์์ ๋, ๊น๋ฐ ํ์์ผ๋ก ์ค๊ณ ๊ฐ์ ์ ํธ๋ฅผ ์ฃผ๊ณ ๋ฐ์๋ค. ์ด๋ฌํ ๋งฅ๋ฝ์์, Critical section์ ์ฌ์ฉํ๋ ์ฐ๋ ๋์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ด๋ฆ์ผ๋ก ๋ถ๊ฒ ๋์๋ค.
์์ ๊ทธ๋ฆผ์ ๋ณด๋ฉด ๊ณต์ ํ๋ ๊ธฐ์ฐป๊ธธ์ด ํ๋์ด๋ค. ์ด ๊ฒฝ์ฐ ๊ณต์ ์์์ด 1์ด๋ผ ๋ณผ ์ ์๋ค. ํ๋์ ๊ธฐ์ฐจ๊ฐ ์ง๋๊ฐ ๋ 1์ ๊ฐ์์ํค๊ณ , ๋ค ์ง๋๊ฐ ๋ค์ 1์ ์ฆ๊ฐ์ํค๋ ์ผ์ ๋ฐ๋ณตํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ๊ธฐ์ฐจ๊ฐ ์ง๋๊ฐ๋ ค๊ณ ํ ๋, Semaphore๊ฐ 0์ธ ๊ฒฝ์ฐ์๋ ์ ์งํ๊ณ 1์ธ ๊ฒฝ์ฐ์ ์์ฐจ์ ์ผ๋ก ์ง๋๊ฐ๊ฒ ํ๋ฉด ํด๊ฒฐ๋๋ค. ์ด๋ ๊ฒ Semaphore๊ฐ 0, 1์ธ ๊ฒฝ์ฐ๋ฅผ Binary Semaphore๋ผ ํ๋ค.
๊ณต์ ์์์ด ๊ผญ 1๊ฐ์ผ ํ์๋ ์๋ค. ์ฌ๋ฌ๊ฐ์ ์์์ธ ์ํฉ๋ ์กด์ฌํ๋ค. ๊ฐ๋ น ์์ ๊ธฐ์ฐจ ๊ทธ๋ฆผ์์ ํต๊ณผํด์ ๊ฐ ์ ์๋ ๊ณต์ ๊ธฐ์ฐป๊ธธ์ด 5๊ฐ๋ผ๋ฉด, ๊ณต์ ์์์ 5์ด๋ค. ์ด๋ฐ ๊ฒฝ์ฐ๋ฅผ counting semaphore๋ผ ํ๋ค.
1. ๊ตฌํ
์์ ์์์์ ๋ณด๋ฏ, ๊น๋ฐ์ ์ด ๋๊ฐ์ง๊ฐ ํ์ํ๋ค. ์ง๋๊ฐ๋ ๊ฒฝ์ฐ์๋ ๊ฐ์, ์ง๋๊ฐ ๋ค์๋ ์ฆ๊ฐ์ด๋ค. ์ด๊ธฐ์๋ P, V๋ก ๋ถ๋ ธ๋ค.(๋ค๋๋๋์์ ๋ง๋ค์ด์ ธ ๋ค๋๋๋์ด์ ์ฝ์์ด๋ค.) ํ์ฌ์๋ P๋ test๋ฅผ ์๋ฏธํ๋ฉฐ acquire()
๋ก ์ฌ์ฉํ๊ณ , V๋ increment๋ฅผ ์๋ฏธํ๋ฉฐ release()
๋ก ์ฌ์ฉํ๋ค. acquire()
๋ ์์์ด ์ฌ์ฉ๊ฐ๋ฅํ์ง ํ์ธํ๊ณ , ์ฌ์ฉ๊ฐ๋ฅํ๋ค๋ฉด ์ฌ์ฉํ๊ณ ๊ทธ๋ ์ง ์๋ค๋ฉด ๋๊ธฐํ๋ค. release()
๋ ์์์ ๋ด๋๊ณ , ๋ค์ ์์์ ์คํ์ํจ๋ค.
์๋ฐ๋ฅผ ํตํด ์ธ๋งํฌ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋จํ ์ดํด๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
class Semaphore {
int value; // number of permits
Semaphore(int value) {
// ...
}
void acquire() {
value--;
if (value < 0) {
// add this process/thread to list
// block
}
}
void release() {
value++;
if (value <= 0) {
// remove a process P from list
// wakeup P
}
}
}
์ ์ฝ๋์์ acquire() ๋ value๊ฐ์ ๊ฐ์์ํค๊ณ ๋ง์ฝ value๊ฐ์ด 0๋ณด๋ค ์์ผ๋ฉด(๊ฐ์ฉ์์์ ๋ชจ๋ ์ฌ์ฉํจ) ์ด๋ฏธ ํด๋น ์๊ณ๊ตฌ์ญ์ ์ด๋ ํ๋ก์ธ์ค๊ฐ ์กด์ฌํ๋ค๋ ์๋ฏธ์ด๋ฏ๋ก ํ์ฌ ํ๋ก์ธ์ค๋ ์ ๊ทผํ์ง ๋ชปํ๋๋ก ๋ง์์ผํ๋ค. ์ด๋ฅผ list๋ผ๋ ๊ธฐ๋ค๋ฆฌ๋ ์ค์ ์ถ๊ฐํ ๋ค block์ ๊ฑธ์ด์ค๋ค.(list๋ ์ผ๋ฐ์ ์ผ๋ก ํ๋ก ๋์ด์๋ค.)
release() ๋ value๊ฐ์ ์ฆ๊ฐ์ํค๊ณ , ๋ง์ฝ value๊ฐ์ด 0๋ณด๋ค ๊ฐ๊ฑฐ๋ ์์ผ๋ฉด ์๊ณ๊ตฌ์ญ์ ์ง์ ํ๋ ค๊ณ ๋๊ธฐํ๋ ํ๋ก์ธ์ค๊ฐ list์ ๋จ์์๋ค๋ ์๋ฏธ์ด๋ฏ๋ก ๊ทธ ์ค์์ ํ๋๋ฅผ ๊บผ๋ด์ด ์๊ณ๊ตฌ์ญ์ ์ํํ ์ ์๋๋ก ํด์ฃผ์ด์ผ ํ๋ค.
์ธ๋งํฌ๋ฅผ ๊ทธ๋ฆผ์ผ๋ก ๋ํ๋ด๋ฉด ์์ ๊ฐ๋ค. list๋ ์ค์ ๋ก ํ๋ก ๋ณผ ์ ์๋ค. acquire()์ ์ํด block๋๋ ํ๋ก์ธ์ค๋ ์ธ๋งํฌ ๋ด๋ถ์ ์๋ ํ์ ์ฝ์ ๋ ํ, ๋ค๋ฅธ ํ๋ก์ธ์ค๊ฐ ์๊ณ๊ตฌ์ญ์ ๋์ค๋ฉด์ release()๋ฅผ ํธ์ถํ์ฌ ์ธ๋งํฌ ํ์ ์๋ ํ๋ก์ธ์ค๋ฅผ ๊นจ์์ผ ํ๋ค.(๋ค์ ready queue๋ก ๋ณด๋ธ๋ค.)
์์์ ์ดํด๋ณธ ๊ฒ์ฒ๋ผ ์ธ๋งํฌ๋ ์ผ๋ฐ์ ์ผ๋ก Mutual exclusion์ ์ํด ์ฌ์ฉ๋๋ค.
08. Process Synchronization
Bank Account Problem(์ํ ๊ณ์ข ๋ฌธ์ ) ํด๊ฒฐ
์ด์ ๊ธ์์ ๋ณด์๋ ์ํ ๊ณ์ข ๋ฌธ์ ์ ์ธ๋งํฌ๋ฅผ ์ ์ฉํด๋ณด์. ์์์ ์๊ณ๊ตฌ์ญ์ BankAccount ํด๋์ค ๋ด๋ถ์ ์ ์ถ๋ ฅํ๋ ๋ถ๋ถ์ธ ๊ฒ์ ๋ณด์๋ค. ์ฌ๊ธฐ์ ์ธ๋งํฌ๋ฅผ ์ ์ฉํด๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
import java.util.concurrent.Semaphore; // ์ธ๋งํฌ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ํ์ผ ๊ฐ์ฅ ์์ ์ถ๊ฐํด์ผ ํ๋ค.
class BankAccount {
int balance;
Semaphore sem;
BankAccount() { // BankAccount ํด๋์ค์ ์์ฑ์๊ฐ ํธ์ถ๋๋ฉด ์ธ๋งํฌ๋ฅผ ๋ง๋ ๋ค.
sem = new Semaphore(1); // value ๊ฐ์ 1๋ก ์ด๊ธฐํํ๋ค.
}
void deposit(int amount) {
try {
sem.acquire(); // ์๊ณ๊ตฌ์ญ์ ๋ค์ด๊ฐ๊ธฐ๋ฅผ ์์ฒญํ๋ค.
} catch (InterruptedException e) {}
/* ์๊ณ ๊ตฌ์ญ */
int temp = balance + amount;
System.out.print("+");
balance = temp;
sem.release(); // ์๊ณ๊ตฌ์ญ์์ ๋๊ฐ๋ค.
}
void withdraw(int amount) {
try {
sem.acquire();
} catch (InterruptedException e) {}
/* ์๊ณ ๊ตฌ์ญ */
int temp = balance - amount;
System.out.print("-");
balance = temp;
sem.release();
}
int getBalance() {
return balance;
}
}
value ๊ฐ์ ์๊ณ๊ตฌ์ญ์ ๋ช ๊ฐ์ ํ๋ก์ธ์ค๋ฅผ ์ ๊ทผํ ๊ฒ์ธ์ง ์ ํ๋ ๊ฒ๊ณผ ๊ฐ๋ค. ์ง๊ธ์ ์๊ณ ๊ตฌ์ญ์ ํ๋์ ํ๋ก์ธ์ค๋ง ์ ๊ทผ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ 1 ๋ก ์ด๊ธฐํ ํ๋ค. (์ ์ฝ๋๋ฅผ ์ ์ธํ ๋ถ๋ถ์ ๋์ผํ๋ค.) ์ด ์ฝ๋๋ฅผ ์ํํ๋ฉด ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
// +,- ์ถ๋ ฅ ์๋ต
balance = 0
์ ์์ ์ผ๋ก ์์ก์ด 0์์ด ๋์จ ๊ฒ์ ํ์ธํ ์ ์๋ค. ์ด ์ฝ๋๋ ์๊ณ๊ตฌ์ญ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์์ผ๋ฏ๋ก ๋ช ๋ฒ์ ์ํํ์ฌ๋ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ์ด ์ถ๋ ฅ๋๋ค.
2. Ordering
์ธ๋งํฌ๋ mutual exclusion๋ฟ ์๋๋ผ ordering์ ํ๊ธฐ ์ํด์๋ ์ฌ์ฉํ๋ค. ์ฆ, ํ๋ก์ธ์ค์ ์คํ ์์๋ฅผ ์ํ๋ ์์๋ก ์ค์ ํ ์ ์๋ค.
์๋ฅผ ๋ค์ด, ํ๋ก์ธ์ค๊ฐ P1, P2 ๋ ๊ฐ๊ฐ ์๋ค๊ณ ๊ฐ์ ํ์. ์ํ๋ ์์๋ P1, P2 ์์ผ๋ก ์คํํ๊ธฐ๋ฅผ ์ํ๋ค. ๊ทธ๋ฌ๋ฉด ์๋์ ๊ฐ์ด ์ค์ ํด์ค ์ ์๋ค.
// ์ด๊ธฐ semaphore ๊ฐ = 0
sem value = 0
|P1|P2| |::|::| ||sem.acquire()| |section 1|section 2| |sem.release()||
P1์ด ๋จผ์ ์คํ๋ ๊ฒฝ์ฐ
- Section 1 ์ด์ ์ ์๋ฌด๋ฐ ๋์์ด ์์ผ๋ฏ๋ก ๋ฐ๋ก ์ํํ๋ค.
- sem.release() ๋ฅผ ๋ง๋๋ฉด value๊ฐ์ 1 ์ฆ๊ฐ์ํค๊ณ , ์ธ๋งํฌ ํ์ ์๋ ํ๋ก์ธ์ค๋ฅผ ๊นจ์์ฃผ๋๋ฐ ํ์ฌ์๋ ํ์ ํ๋ก์ธ์ค๊ฐ ์์ผ๋ฏ๋ก ์๋ฌด ๋์๋ ํ์ง ์๋๋ค.
- P2๊ฐ ์คํ๋๋ค.
- P2์ sem.acquire() ๋ฅผ ๋ง๋๋ฉด ํ์ฌ value๊ฐ์ 1์ด๊ณ ์ด๋ฅผ 1๊ฐ์์ํค๋ฉด 0์ด ๋๋ค. value = 0์ด๋ฉด block์ ํ์ง ์์ผ๋ฏ๋ก, ๋ฌด์ฌํ Section 2๊ฐ ์ํ๋๋ค.
P2๊ฐ ๋จผ์ ์คํ๋ ๊ฒฝ์ฐ
- Section 2 ์ด์ ์ sem.acquire() ๊ฐ ์์ผ๋ฏ๋ก ์ด๋ฅผ ์ํํ๋๋ฐ, ํ์ฌ value๊ฐ์ 0์ด๊ณ ์ด๋ฅผ 1 ๊ฐ์ ์ํค๋ฉด -1 ์ด ๋๋ค. value๊ฐ์ด ์์๋ฉด ํด๋น ํ๋ก์ธ์ค๋ฅผ block์ํจ๋ค.(์ธ๋งํฌ ํ์ ์ฝ์ ํ๋ค.)
- P1์ด ์คํ๋๋ฉด Section 1์ด ๋ฐ๋ก ์ํ๋๋ค.
- sem.release() ๋ฅผ ๋ง๋๋ฉด value๊ฐ์ 1 ์ฆ๊ฐ์ํค๊ณ , ์ธ๋งํฌ ํ์ ์๋ P2 ํ๋ก์ธ์ค๋ฅผ ๊นจ์์ค๋ค.(ํ์ฌ value = 0)
- P2์ Section 2๊ฐ ์ํ๋๋ค.
์์์ ๋ ๊ฐ์ง ๊ฒฝ์ฐ๋ฅผ ์ดํด๋ณด์๋ฏ์ด, P1, P2 ๋ ์ค ์ด๋ ๊ฒ์ ๋จผ์ ์คํํ์ฌ๋ ๊ฒฐ๊ณผ์ ์ผ๋ก P1 โ P2 ์์๋ก ์ํํ๋ ๊ฒ์ ์ ์ ์๋ค.
์ ๊ธ ์ถ๊ธ ์์๋ก ์ํ๊ณ์ข ๋ฌธ์ ํด๊ฒฐํ๊ธฐ
์์์ ๊ณ์ ์ดํด๋ดค๋ ์ํ๊ณ์ข ๋ฌธ์ ์์ ordering์ ์ ์ฉํด๋ณด์. ํ๋ก์ธ์ค์ ์คํ ์์๋ ๋ฐ๋์ ์ ๊ธ, ์ถ๊ธ ์์๋ก ์ํํด์ผํ๋ค.
class BankAccount {
int balance;
Semaphore sem, semOrder;
BankAccount() {
sem = new Semaphore(1);
semOrder = new Semaphore(0); // Ordeing์ ์ํ ์ธ๋งํฌ
}
void deposit(int amount) {
try {
sem.acquire();
} catch (InterruptedException e) {}
int temp = balance + amount;
System.out.print("+");
balance = temp;
sem.release();
semOrder.release(); // block๋ ์ถ๊ธ ํ๋ก์ธ์ค๊ฐ ์๋ค๋ฉด ๊นจ์์ค๋ค.
}
void withdraw(int amount) {
try {
semOrder.acquire(); // ์ถ๊ธ์ ๋จผ์ ํ๋ ค๊ณ ํ๋ฉด blockํ๋ค.
sem.acquire();
} catch (InterruptedException e) {}
int temp = balance - amount;
System.out.print("-");
balance = temp;
sem.release();
}
int getBalance() {
return balance;
}
}
์์ฒ๋ผ ์ฝ๋๋ฅผ ์์ ํ ์ ์๋ค. Ordering์ ์ํ semOrder ์ธ๋งํฌ ๋ณ์๋ฅผ ์ ์ธํ๊ณ , ์ถ๊ธํ๋ ๋์ ์์ acquire()
, ์
๊ธํ๋ ๋์ ๋ค์ release()
๋ฅผ ์ถ๊ฐํ์๋ค.
+++++++++++++++++++++++++------------+++++-----++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++------------------------------------------
----------------------------------------
balance = 0
์คํ ๊ฒฐ๊ณผ๋ ์์ ๊ฐ๋ค. +(์ ๊ธ)๊ฐ ๋งจ ์์์ ์คํํ ๋ชจ์ต์ ๋ณผ ์ ์๋ค.(์ ๊ธ, ์ถ๊ธ ํ์๋ 100๋ฒ์ผ๋ก ์ค์๋ค.)
๋ง์ฝ, ์ ๊ธ, ์ถ๊ธ, ์ ๊ธ, ์ถ๊ธ, โฆ ๊ต๋๋ก ์ถ๋ ฅํ๋๋ก ํ๋ ค๋ฉด ์ธ๋งํฌ๋ฅผ ๋ ๊ฐ ์ฌ์ฉํ์ฌ ์๋์ ๊ฐ์ด ๊ตฌํํ ์ ์๋ค.
void deposit(int amount) {
try {
sem.acquire();
int temp = balance + amount;
System.out.print("+");
balance = temp;
sem.release();
semWithraw.release();
semDeposit.acquire(); // ์
๊ธํ์๋ ๋ฐ๋์ ์ถ๊ธ์ ํด์ผ ํ๋ฏ๋ก ์์ ์ blockํ๋ค.
} catch (InterruptedException e) {}
}
void withdraw(int amount) {
try {
semWithraw.acquire(); // ์
๊ธ๋ณด๋ค ๋จผ์ ์ํํ๋ ๊ฒ์ ๋ง๋๋ค.
sem.acquire();
} catch (InterruptedException e) {}
int temp = balance - amount;
System.out.print("-");
balance = temp;
sem.release();
semDeposit.release(); // ์ถ๊ธ ์ํ์ด ์๋ฃ๋๋ฉด block๋์๋ ์
๊ธ ํ๋ก์ธ์ค๋ฅผ ๊นจ์์ค๋ค.
}
int getBalance() {
return balance;
}
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
balance = 0
Reference
- KOCW ์ํฌ์ฌ ๊ต์๋ - ์ด์์ฒด์
- ์ํฌ์ฌ ๊ต์๋ ๋ธ๋ก๊ทธ(์ํ ๊ธฐ์ถ ๋ฌธ์ )
- codemcd ๋์ ์ ๋ฆฌ๊ธ
- Operating System Concepts, 9th Edition - Abraham Silberschatz