ν‹°μŠ€ν† λ¦¬ λ·°

728x90
λ°˜μ‘ν˜•

Producer - Consumer Problem

 νŠΉμ • ν”„λ‘œμ„ΈμŠ€λŠ” 데이터λ₯Ό μƒμ‚°ν•˜κ³ , νŠΉμ • ν”„λ‘œμ„ΈμŠ€λŠ” μƒμ‚°λœ 데이터λ₯Ό 톡해 μ²˜λ¦¬ν•˜λŠ” μž‘μ—…κ³Ό 같이 μƒμ„±μž-μ†ŒλΉ„μžκ°€ μžˆλŠ” ν”„λ‘œκ·Έλž¨μ—μ„œ λ°œμƒν•  수 μžˆλŠ” λ¬Έμ œμ΄λ‹€. λ§Œμ•½ μƒμ‚°λ˜μ§€ μ•Šμ€ κ²½μš°μ— 데이터λ₯Ό μ‚¬μš©ν•˜λŠ” μ†ŒλΉ„μžκ°€ 데이터λ₯Ό κ°€μ Έκ°€κ²Œ λœλ‹€λ©΄ μ›μΉ˜ μ•ŠλŠ” 데이터 (μ“°λ ˆκΈ° κ°’)을 κ°€μ Έκ°€κ²Œ 될 κ°€λŠ₯성이 크닀. λ”°λΌμ„œ 각각의 ν”„λ‘œμ„ΈμŠ€(μ“°λ ˆλ“œ)둜 λΆ€ν„° μƒμ„±μž - μ†ŒλΉ„μžκ°€ μ‘΄μž¬ν•œλ‹€λ©΄ 생성, μ†ŒλΉ„ 순으둜 진행될 수 μžˆλ„λ‘ 동기화가 ν•„μš”ν•˜λ‹€.

 

import java.util.concurrent.Semaphore;

class Buffer {
    int[] buf;
    int size;
    int count;
    int in;
    int out;
    Semaphore mutex, full, empty;

    Buffer(int size) {
        buf = new int[size];
        this.size = size;
        count = in = out = 0;
        mutex = new Semaphore(1);
        full = new Semaphore(0);
        empty = new Semaphore(size);
    }
    void insert(int item) {
        try{
            empty.acquire();
            mutex.acquire();
            buf[in] = item;
            in = (in+1)%size;
            count++;
            mutex.release();
            full.release();
        } catch (InterruptedException e) {}
    }
    int remove() {
        try {
            full.acquire();
            mutex.acquire();
            int item = buf[out];
            out = (out+1)%size;
            count--;
            mutex.release();
            empty.release();
            return item;
        } catch (InterruptedException e) {}

        return -1;
    }
}


class Producer extends Thread {
    Buffer b;
    int N;
    Producer(Buffer b, int N) {
        this.b = b; this.N = N;
    }
    public void run() {
        for (int i=0; i<N; i++)
            b.insert(i);
    }
}

class Consumer extends Thread {
    Buffer b;
    int N;
    Consumer(Buffer b, int N) {
        this.b = b; this.N = N;
    }
    public void run() {
        int item;
        for (int i=0; i<N; i++)
            item = b.remove();
    }
}

class Test {
    public static void main(String[] arg) {
        Buffer b = new Buffer(100);
        Producer p = new Producer(b, 10000);
        Consumer c = new Consumer(b, 10000);
        p.start();
        c.start();
        try {
            p.join();
            c.join();
        } catch (InterruptedException e) {}
        System.out.println("Number of items in the buf is " + b.count);
    }
}

 μœ„μ˜ μžλ°” μ½”λ“œμ™€ 같이 μƒμ„±μž(Producer), μ†ŒλΉ„μž(Consmer)λŠ” λ²„νΌλΌλŠ” 객체λ₯Ό κ³΅μœ ν•˜μ—¬ 값을 μΆ”κ°€ν•˜κ±°λ‚˜ μ‚­μ œν•œλ‹€. λ‹¨μˆœνžˆ μ„Έλͺ¨ν¬μ–΄λ₯Ό μ μš©ν•  경우 μ„Έλͺ¨ν¬μ–΄ νšλ“μ΄ ν•„μš”ν•œ 경우 Busy Wating을 ν•˜κ²Œ 되며 μ΄λŠ” λΉ„νš¨μœ¨μ μ΄λ‹€. λ”°λΌμ„œ 2개의 μ„Έλ§ˆν¬μ–΄λ₯Ό μΆ”κ°€ν•˜μ—¬ Busy Wating을 λ°©μ§€ν•˜λ©° μƒμ„±μž, μ†ŒλΉ„μž 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€.

  • empty : 버퍼 크기 만큼 μ΄ˆκΈ°ν™” ν•˜κ³ , μƒˆλ‘œμš΄ 값이 μΆ”κ°€ 될 경우 1 κ°μ†Œ μ‹œν‚¨κ³ , 값이 μ‚­μ œ 될 경우 1 증가 μ‹œν‚¨λ‹€.
  • full : empty와 λ°˜λŒ€λ˜λŠ” 역할을 μˆ˜ν–‰ν•œλ‹€.

 

Dining Philosopher Problem

 μ›ν˜• ν…Œμ΄λΈ”μ— 5λͺ…μ˜ μ² ν•™μžκ°€ 있고, 젓가락은 5개만 μžˆλŠ” 상황이 μžˆλ‹€. 각 μ² ν•™μžλŠ” μƒκ°ν•˜κ³  μ‹μ‚¬ν•˜λŠ” 과정을 λ°˜λ³΅ν•˜λ©°, 식사λ₯Ό ν•˜κΈ° μœ„ν•΄μ„œλŠ” 2개의 젓가락이 μžˆμ–΄μ•Ό ν•œλ‹€. μ›ν˜• ν…Œμ΄λΈ”μ— 앉은 μ² ν•™μžλ“€μ€ μžμ‹ μ˜ μ™Όμͺ½μ˜ 젓가락을 νšλ“ν•˜κ³ , 였λ₯Έμͺ½ 젓가락이 νšλ“κ°€λŠ₯ν•œ 경우 식사λ₯Ό μ‹œμž‘ν•œλ‹€. 식사가 λμ΄λ‚˜λ©΄ μ™Όμͺ½ 젓가락을 내렀두고, 였λ₯Έμͺ½ 젓가락을 λ‚΄λ €λ‘”λ‹€.

 

import java.util.concurrent.Semaphore;

class Philosopher extends Thread {
    int id; // philosopher id
    Semaphore lstick, rstick; // left, right chopsticks
    Philosopher(int id, Semaphore lstick, Semaphore rstick) {
        this.id = id;
        this.lstick = lstick;
        this.rstick = rstick;
    }

    public void run() {
        try {
            while (true) {
                lstick.acquire();
                rstick.acquire();
                eating();
                lstick.release();
                rstick.release();
                thinking();
            }
        }catch (InterruptedException e) { }
    }

    void eating() {
        System.out.println("[" + id + "] eating");
    }

    void thinking() {
        System.out.println("[" + id + "] thinking");
    }
}

class Test {
    static final int num = 5; // number of philosphers & chopsticks
    public static void main(String[] args) {
        int i;
        /* chopsticks */
        Semaphore[] stick = new Semaphore[num];
        for (i=0; i<num; i++)
            stick[i] = new Semaphore(1);
        /* philosophers */
        Philosopher[] phil = new Philosopher[num];
        for (i=0; i<num; i++)
            phil[i] = new Philosopher(i, stick[i], stick[(i+1)%num]);
        /* let philosophers eat and think */
        for (i=0; i<num; i++)
            phil[i].start();
    }
}

 μœ„μ˜ μ½”λ“œλŠ” μ‹μ‚¬ν•˜λŠ” μ² ν•™μž λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆλŠ” μžλ°” μ½”λ“œμ΄λ‹€. ν•˜μ§€λ§Œ 이 μ½”λ“œλŠ” deadlock에 빠질 수 μžˆλ‹€. 예λ₯Ό λ“€μ–΄ λͺ¨λ“  μ² ν•™μžκ°€ λ™μ‹œμ— μ™Όμͺ½ 젓가락을 집어듀면 (μ„Έλ§ˆν¬μ–΄λ₯Ό νšλ“ν•˜λ©΄) λͺ¨λ“  μ² ν•™μžλ“€μ€ 였λ₯Έμͺ½ 젓가락을 집어듀 수 μ—†μ–΄ starvation에 λΉ μ§€κ²Œ λœλ‹€. μ΄λŠ” 잘λͺ»λœ μ„Έλ§ˆν¬μ–΄ μ„€μ •μœΌλ‘œ ν”„λ‘œμ„ΈμŠ€μ˜ μž‘μ—…μ΄ μ§„ν–‰λ˜μ§€ μ•ŠλŠ” λŒ€ν‘œμ μΈ 상황이며, λ§Œμ•½ μš΄μ˜μ²΄μ œμ—μ„œ deadlock이 λ°œμƒν•œλ‹€λ©΄ μ΄λŠ” 컴퓨터λ₯Ό μ‚¬μš©ν•  수 μ—†λŠ” 상황이 될 μˆ˜λ„ μžˆλ‹€.

728x90
λ°˜μ‘ν˜•
λŒ“κΈ€
κΈ€ 보관함
μ΅œκ·Όμ— 올라온 κΈ€
μ΅œκ·Όμ— 달린 λŒ“κΈ€