ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

728x90
๋ฐ˜์‘ํ˜•

 ํ”„๋กœ์„ธ์Šค ๊ฐ„์˜ ์ •๋ณด๋ฅผ ์ฃผ๊ณ  ๋ฐ›๊ฑฐ๋‚˜, ํ•˜๋‚˜์˜ ๊ณต์œ ๋œ ์˜์—ญ์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์—๋Š” ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํ”„๋กœ์„ธ์Šค A๋Š” 1๋ฒˆ์ง€ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— 10์ด๋ผ๋Š” ๊ฐ’์„ ์ฝ์–ด ์˜ค๊ณ ์žํ•˜์˜€์œผ๋‚˜, ํ”„๋กœ์„ธ์Šค B๊ฐ€ ํ”„๋กœ์„ธ์Šค A๊ฐ€ ์ฝ๋Š” ์ง์ „์— 20์ด๋ผ๋Š” ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•ด ๋ฒ„๋ฆฌ๋ฉด ์›ํ•˜์ง€ ์•Š๋Š” ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ์ƒํ˜ธ์ ์œผ๋กœ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ํ”„๋กœ์„ธ์Šค๋“ค์„ Cooperating Process๋ผ๊ณ  ํ•œ๋‹ค. ์ด์™€ ๋ฐ˜๋Œ€์ธ ๊ฒฝ์šฐ Independent Process๋ผ๊ณ  ํ•œ๋‹ค.

 

 ๊ฐ ํ”„๋กœ์„ธ์Šค๋กœ ์ธํ•ด ๊ณต์œ  ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ๋™๊ธฐํ™”(Synchronization)๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์•ž์„œ ๋งํ•œ ๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ์—์„œ ์›์น˜ ์•Š๋Š” ๊ฐ’์„ ๋ฐ˜ํ™˜๋ฐ›์ง€ ์•Š์œผ๋ ค๋ฉด, ํ”„๋กœ์„ธ์Šค A โ†’ ํ”„๋กœ์„ธ์Šค B์˜ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•  ๊ฒฝ์šฐ ์ด์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๊ณต์œ  ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๋ฒˆ์— ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค.

 

Bank Account Problem (์€ํ–‰ ๊ณ„์ขŒ ๋ฌธ์ œ)

 ๋™๊ธฐํ™” ๋ฌธ์ œ ์ค‘ ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ณ , ๋Œ€ํ‘œ์ ์ธ ๋ฌธ์ œ๊ฐ€ ์€ํ–‰ ๊ณ„์ขŒ์— ๊ธˆ์•ก์ด ์ž…์ถœ๊ธˆ ๋  ๊ฒฝ์šฐ์ด๋‹ค. ๋งŒ์•ฝ ์ž…์ถœ๊ธˆ ๊ณผ์ •์˜ ์ˆœ์œ„๊ฐ€ ๋ณด์žฅ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ์›์น˜ ์•Š๋Š” ๊ฒฐ๊ณผ๋ฅผ ์ดˆ๋ž˜ํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.

 

class BankAccount {
    int balance;
    void deposit(int amount) {
        balance += amount;
    }

    void withdraw(int amount) {
        balance -= amount;
    }

    int getBalance() {
        return balance;
    }
}

class Parent extends Thread {
    BankAccount b;
    int count;
    Parent(BankAccount b, int count) {
        this.b = b;
        this.count = count;
    }

    public void run() {
        for (int i = 0; i < count; i++)
            b.deposit(1);
    }
}

class Child extends Thread {
    BankAccount b;
    int count;
    Child(BankAccount b, int count) {
        this.b = b;
        this.count = count;
    }

    public void run() {
        for (int i = 0; i < count; i++)
            b.withdraw(1);
    }
}


public class Test {
    static final int MAX = 100;
    public static void main(String[] args) throws InterruptedException {
        // ์€ํ–‰ ๊ณ„์ขŒ ๊ฐ์ฒด ์ƒ์„ฑ
        BankAccount b = new BankAccount();
        // ์“ฐ๋ ˆ๋“œ ๊ฐ์ฒด ์ƒ์„ฑ
        Parent p = new Parent(b, MAX);
        Child c = new Child(b, MAX);
        // ์“ฐ๋ ˆ๋“œ ์‹คํ–‰
        p.start();
        c.start();
        p.join();
        c.join();
        // ์ž”์•ก ์ถœ๋ ฅ
        System.out.println("Final balance = " + b.getBalance());
    }
}

 ์œ„์˜ ๊ฐ„๋‹จํ•œ ์ž๋ฐ” ์ฝ”๋“œ์™€ ๊ฐ™์ด ์ž…๊ธˆ์„ ํ•˜๋Š” ๊ฐ์ฒด์ธ Parent์™€ ์ถœ๊ธˆ์„ ํ•˜๋Š” ๊ฐ์ฒด์ธ Child๊ฐ€ BanckAccount๋ผ๋Š” ๊ณต์šฉ์ž์›์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. ์˜ˆ์ œ ์ฝ”๋“œ๋Š” ์‹ฌํ”Œํ•˜์—ฌ ๋‘๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ๊ฐ€ ๊ณต์šฉ์ž์›์„ ์‚ฌ์šฉํ•˜๋ฉฐ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์›์น˜์•Š๋Š” ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ์™ธ์™€ ๊ฐ™์€ ์ด์œ ๋Š” ์ž…์ถœ๊ธˆ์— ๋Œ€ํ•œ ์ˆœ์„œ๊ฐ€ ๋ณด์žฅ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. (์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋งค ์‹คํ–‰๋งˆ๋‹ค ์ž…์ถœ๊ธˆ์˜ ์ˆœ์„œ๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.)

 

์ž„๊ณ„ ๊ตฌ์—ญ (Critical Section)

 ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค(์“ฐ๋ ˆ๋“œ)๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๊ณต์œ ์ž์›์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•˜๋Š” ์ฝ”๋“œ ์˜์—ญ์„ ์ž„๊ณ„ ๊ตฌ์—ญ์ด๋ผ๊ณ  ํ•œ๋‹ค. ์€ํ–‰ ๊ณ„์ขŒ ๋ฌธ์ œ ์ฝ”๋“œ์—์„œ๋Š” deposit, withdraw ๋ฉ”์†Œ๋“œ๊ฐ€ ์ด์— ํ•ด๋‹นํ•œ๋‹ค.

 

์ž„๊ณ„ ๊ตฌ์—ญ์— ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค(์“ฐ๋ ˆ๋“œ)๊ฐ€ ์ง„์ž…ํ•˜๋”๋ผ๋„ ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์กฐ๊ฑด์„ ๋งŒ์กฑ์‹œํ‚ฌ ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

  1. Mutual Exculsion : ์ž„๊ณ„ ๊ตฌ์—ญ์— ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค(์“ฐ๋ ˆ๋“œ)๊ฐ€ ์ง„์ž…ํ•œ ์ƒํƒœ๋ผ๋ฉด ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ๋Š” ์ง„์ž… ํ•  ์ˆ˜ ์—†๋‹ค.

  2. Progess : 1์˜ ์กฐ๊ฑด์„ ์ถฉ์กฑ์‹œํ‚ค๊ธฐ ์œ„ํ•ด, ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค(์“ฐ๋ ˆ๋“œ)๋“ค์€ ๋Œ€๊ธฐ๊ฐ€ ํ•„์š”ํ•  ๊ฒƒ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ž„๊ณ„ ๊ตฌ์—ญ์˜ ๋™์ž‘์€ ๊ฐ„๋‹จํ•˜๊ณ  ์งง์€ ์‹œ๊ฐ„ ๋‚ด์— ์ด๋ฃจ์–ด์ ธ์•ผ ํ•œ๋‹ค.

  3. Bounded Wating : ์ž„๊ณ„ ๊ตฌ์—ญ์„ ์ง„์ž…ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค(์“ฐ๋ ˆ๋“œ)๋Š” ์ผ์ • ์‹œ๊ฐ„ ๋‚ด์— ์ง„์ž…ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

 

ํ”„๋กœ์„ธ์Šค(์“ฐ๋ ˆ๋“œ) ๋™๊ธฐํ™”

์•ž์„œ ๋ฐœ์ƒํ•˜๋Š” ๋™์‹œ์— ์ž„๊ณ„๊ตฌ์—ญ์— ์ ‘๊ทผํ•˜๋Š” ๋ฌธ์ œ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋™๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ๋™๊ธฐํ™”๋ฅผ ํ†ตํ•ด ํ”„๋กœ์„ธ์Šค์˜ ์‹คํ–‰ ์ˆœ์„œ๋ฅผ ์ œ์–ด ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ž„๊ณ„ ๊ตฌ์—ญ ์ง„์ž…์„ ์œ„ํ•œ ๋ถˆํ•„์š”ํ•œ Wating์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Semaphore (์„ธ๋งˆํฌ์–ด)

 ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ง„์ž…ํ•˜๊ธฐ ์œ„ํ•ด, ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ํš๋“ํ•˜๊ณ  ๊ถŒํ•œ์„ ํš๋“ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋™๊ธฐํ™” ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค. ์ž๋ฐ”์˜ ๊ฒฝ์šฐ ์“ฐ๋ ˆ๋“œ ์‚ฌ์šฉ ์‹œ java.util.concurrent.Semaphore๋ฅผ ํ†ตํ•ด ์„ธ๋งˆํฌ์–ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ, ์ž„๊ณ„ ๊ตฌ์—ญ์˜ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

BankAccount Problem (USE Semaphore)

import java.util.concurrent.Semaphore;

class BankAccount {
    int balance;
    Semaphore s;

    BankAccount() {
        s = new Semaphore(1);
    }

    void deposit(int amount) {
        try {
            s.acquire();
        } catch (InterruptedException e) { }

        balance += amount;

        s.release();
    }

    void withdraw(int amount) {
        try {
            s.acquire();
        } catch (InterruptedException e) { }
        
        balance -= amount;

        s.release();
    }

    int getBalance() {
        return balance;
    }
}

๋™์‹œ์— ์—ฌ๋Ÿฌ ์“ฐ๋ ˆ๋“œ๊ฐ€ ์ž„๊ณ„ ๊ตฌ์—ญ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•ด ์ž๋ฐ”์—์„œ๋Š” ์œ„์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ์กด ์ฝ”๋“œ์™€ ๋‹ฌ๋ฆฌ BackAccount Generator์—์„œ ์„ธ๋ชจํฌ์–ด ๊ฐ์ฒด๋ฅผ ํ• ๋‹นํ•˜๊ณ , ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ permits์˜ ๊ฐ’์„ 1๋กœ ์„ค์ •ํ•œ๋‹ค. ๋˜ํ•œ, deposit๊ณผ withdraw ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, ์„ธ๋ชจํฌ์–ด๋ฅผ ํš๋“/ ํ•ด์ œ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์ž„๊ณ„ ๊ตฌ์—ญ์— ํ•˜๋‚˜์˜ ์“ฐ๋ ˆ๋“œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Ordering

 ๋‹จ์ˆœํžˆ ์„ธ๋ชจํฌ์–ด๋ฅผ ์ ์šฉํ•  ๊ฒฝ์šฐ์˜ ๋ฌธ์ œ์ ์€ ์—ฌ์ „ํžˆ ์ž…์ถœ๊ธˆ์— ๋Œ€ํ•œ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ์‹ค์ œ ์ƒํ™ฉ์™€ ๋น„์Šทํ•˜๊ฒŒ ์ž…์ถœ๊ธˆ์— ๋”ฐ๋ฅธ ์ˆœ์„œ๋ฅผ ๋ณด์žฅ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.

 

class BankAccount {
    int balance;
    Semaphore critical;
    Semaphore order;

    BankAccount() {
        critical = new Semaphore(1);
        order = new Semaphore(0);
    }

    void deposit(int amount) {
        try {
            critical.acquire();
        } catch (InterruptedException e) { }

        balance += amount;

        critical.release();
        order.release();
    }

    void withdraw(int amount) {
        try {
            order.acquire();
            critical.acquire();
        } catch (InterruptedException e) { }

        balance -= amount;

        critical.release();
    }

    int getBalance() {
        return balance;
    }
}

 ์ž„๊ณ„ ๊ตฌ์—ญ์— ๋Œ€ํ•œ ์ ‘๊ทผ์€ ์„ธ๋ชจํฌ์–ด ํš๋“ / ํ•ด์ œ๋ฅผ ํ†ตํ•ด ๋ณด์žฅํ•˜์˜€๋‹ค. ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์„ธ๋ชจํฌ์–ด๋ฅผ 0์œผ๋กœ ์„ค์ •ํ•˜๊ณ , ์ž…๊ธˆํ•  ๋•Œ ํ•ด์ œํ•˜๊ณ  ์ถœ๊ธˆ ํ• ๋•Œ ํš๋“ํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

728x90
๋ฐ˜์‘ํ˜•
๊ธ€ ๋ณด๊ด€ํ•จ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€