본문 바로가기
안 씀/자료구조-예제&실습

큐의 응용: 버퍼

by unhyepnhj 2024. 7. 15.

큐는 서로 다른 속도로 실행되는 두 프로세스 간의 상호 작용을 조화키는 버퍼의 역할을 할 수 있다. 대개 데이터를 생산하는 생산자 프로세스가 있고, 데이터를 소비하는 소비자 프로세스가 있을 때 이 사이에 큐로 구성되는 버퍼가 존재한다. 생산자-소비자 프로세스 외에도 신호등을 순차적으로 제어하는 교통 관리 시스템, 프로세스들을 저장하는 CPU 스케줄링 등의 큐 응용 분야가 있다.

 

프로그램 5-3 큐 응용 프로그램

- 큐에 일정한 비율(20%)로 난수를 생성하여 입력하고, 일정한 비율(10%)로 큐에서 정수를 꺼내는 프로그램 

- 생산자(20%)가 소비자(10%)보다 빠르므로 큐가 포화 상태가 될 가능성이 높아짐

#include <stdio.h>
#include <stdlib.h>
#define MAX_QUEUE_SIZE 5

typedef int element;
typedef struct {
	int front, rear;
	element data[MAX_QUEUE_SIZE];
} QueueType;

void init_queue(QueueType* q) {
	q->front = 0;
	q->rear = 0;
}
void error(char* message) {
	fprintf(stderr, "%s\n", message);
	exit(1);
}
int is_full(QueueType* q) {
	return(q->front == (q->rear + 1) % MAX_QUEUE_SIZE);
}
int is_empty(QueueType* q) {
	return(q->front == q->rear);
}
void enqueue(QueueType* q, element item) {
	if (is_full(q)) 
		error("큐가 포화 상태입니다.");
	else {
		q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
		q->data[q->rear] = item;
	}
}
element dequeue(QueueType* q) {
	if (is_empty(q))
		error("큐가 공백 상태입니다.");
	else {
		q->front = (q->front + 1) % MAX_QUEUE_SIZE;
		return q->data[q->front];
	}
}
element peek(QueueType* q) {
	if (is_empty(q))
		error("큐가 공백 상태입니다.");
	else
		return q->data[(q->front + 1) % MAX_QUEUE_SIZE];
}
void queue_print(QueueType* q) {
	printf("QUEUE(front=%d rear=%d) = ", q->front, q->rear);
	if (!is_empty(q)) {
		int i = q->front;
		do {
			i = (i + 1) % (MAX_QUEUE_SIZE);
			printf("%d |   ", q->data[i]);
			if (i == q->rear)
				break;
		} while (i != q->front);
	}
	printf("\n");
}

int main(void) {
	QueueType queue;
	int element;

	init_queue(&queue);
	srand(time(NULL));	//난수

	for (int i = 0; i < 100; i++) {
		if (rand() % 5 == 0) 
			enqueue(&queue, rand() % 100);
		queue_print(&queue);
	}
	return 0;
}

>>