Bounded-Buffer PS

0x10. Problem

0x11. situation

WHO
  • Producer: 데이터를 생성해서 buffer에 넣는 entity

  • Consumer: buffer에서 데이터를 꺼내서 사용하는 entity

  • Buffer: fixed size를 가진 shared memory (queue 형태)

dynamics
  • Producer → buffer에 item push

  • Consumer → buffer에서 item pop

  • 동시에 여러 producer/consumer가 접근 가능 (concurrent execution)

constraint
  • buffer가 가득 차면 → producer는 더 이상 넣으면 안됨

  • buffer가 비어 있으면 → consumer는 꺼낼 수 없음

0x12. aspect


0x20. IDEA

0x21. 두 종류의 제어를 분리해야 함.

  • Mutual Exclusion: 한 번에 한 execution(process/thread)만 buffer를 만지게 한다

  • resource availability control: 넣을 수 있을 때만 넣고, 꺼낼 수 있을 때만 꺼내야 함.

    • -> empty개수, full 개수에 대한 정보 관리가 필요

0x30. Solution

0x31. w/ Semaphores

Semaphores

  • 접근 제어(Mutual Exclusion)을 위해 binary semaphore를 사용
  • bounded특성(resource availability control)을 관리하기 위해 integer semaphore를 사용
    • empty개수 관리 -> empty buffer
    • full 개수 관리 -> full buffer
IMPL
semaphore N_empty_buf = N; 
semaphore N_full_buf = 0; 
semaphore S_mutex = 1; 
 
// producer 
while (1) {
	item = produce_item();
	
	P(N_empty_buf);
	P(S_mutex);
	
	insert_item(item); // write to buf 
	
	V(S_mutex);
	V(N_full_buf);
}
 
 
// consumer 
while (1) {
	P(N_full_buf);
	P(S_mutex);
	
	item = remove_item(); // read from buf 
	
	V(S_mutex);
	V(N_empty_buf);
	
	consume_item(item);
}
 

0x32. w/ monitor

Monitor

IMPL
monitor BoundedBuffer {
 
    Item buf[N];
    int in = 0;
    int out = 0;
    int count = 0;
    
    condition notFull;
    condition notEmpty;
    
	void produce() {
		while (count == N) {
			notFull.wait();
		}
		
		buf[in] = item;
        in = (in + 1) % N;
        count++;
        notEmpty.signal();
	}
	
	// consumer 
	Item consume() {
		Item item; 
		
		while (count == 0) {
			notEmpty.wait();
		}
		
		item = buf[out]; 
		out = (out + 1) % N;
		count--;
		
		notFull.signal();
		return item;
	}
}
 
void producer_thread() {
    while (1) {
        Item item = produce_item();   // 데이터 생성 (independent)
 
        buffer.produce(item);         // monitor 호출
    }
}
 
void consumer_thread() {
    while (1) {
        Item item = buffer.consume();  // monitor 호출
 
        consume_item(item);            // 데이터 사용
    }
}