본문 바로가기

programmer/Programming

원형 큐(circuit queue) 예제

통신을 위한 메시지 큐나 순환되는 큐 구조를 만들고 싶을 때 원형 큐를 많이 사용한다. C로 구현한 원형 큐 구현 예제는 인터넷에 많으므로 원형 큐의 데이터를 구조체로 체우는 예제를 공유해 본다.

Queue 사이즈를 동적으로 만들기 위해서 MaxSize를 사용했을 뿐 이와 같은 작업이 필요 없다면 MAX_SIZE로 대체 가능하다.

원형 큐에 들어가는 구조체 데이터는 typedef P_convert element이며 P_convert는 구조체이다. P_convert 대신에 자신이 원하는 구조체를 만들어 사용하면 된다.

파일명: packet_queue.h

#include "server_type.h"

#define TRUE 1
#define FALSE 0
#define ERROR -1
#define MAX_SIZE 100

typedef P_convert element;
typedef P_convert* pelement;


typedef struct __circleQueue {
    int rear;
    int front;
    int MaxSize;
    P_convert* data;
    //element data[MAX_SIZE];
}Queue;

void enqueue(Queue *q, element data);
element dequeue(Queue *q);
void init_queue(Queue *q, int qSize);
int is_full(Queue *q);
int is_empty(Queue *q);
void queue_print(Queue q);

/*		큐 초기화		*/
void init_queue(Queue *q,int qSize) {
    if(qSize>MAX_SIZE)
    {
        qSize=MAX_SIZE;
        printf("MAX_SIZE Over! (it is assigned %d)",MAX_SIZE);
    }
    q->front = 0;
    q->rear = 0;
    q->MaxSize = qSize;
#ifdef __cplusplus
	//c++에서 구조체 배열 동적 할당하는 방법
    q->data = (element*)malloc(sizeof(element)*qSize);
#else
	//c에서 구조체 배열 동적 할당하는 방법
    q->data = (struct element*)malloc(sizeof(element)*qSize);
#endif



}
void finish_queue(Queue *q)
{
    if(q->data != NULL)
    {
        free(q->data);
    }

}
/*		큐에 데이터 삽입		*/
void enqueue(Queue *q, element data) {
    if (is_full(q)) {
        printf("\n포화 큐\n");
        return;
    }
    else {
        q->rear = (q->rear + 1) % (q->MaxSize);	//	원형큐이므로, front+1 == q->MaxSize이면 0으로 돌아가게 하기 위함
        q->data[q->rear] = data;	//	front 하나 증가하고, data 추가
    }
    return;
}

/*		큐 데이터 꺼내기		*/
element dequeue(Queue *q) {
    if (is_empty(q)) {
        printf("공백큐\n");
    }
    q->front = (q->front + 1) % (q->MaxSize);
    return q->data[q->front];
}

/*		공백 상태인지 여부		*/
int is_empty(Queue *q) {
    if (q->front == q->rear) return TRUE;
    else return FALSE;
}

/*		포화 상태인지 여부		*/
int is_full(Queue *q) {
    if (((q->rear + 1) % q->MaxSize) == q->front) return TRUE;
    else return FALSE;
}

/*		현재 큐 프린트		*/
void queue_print(Queue q) {
    int i = q.front;
    if (is_empty(&q)) {
        printf("\n공백 큐\n");
        return;
    }

    do {
        i = (i + 1) % q.MaxSize;
        printf("%d , ", q.data[i].P_body.cheader.msgID);
        printf(" %d , ", q.data[i].P_body.cheader.type);
        printf(" %d , ", q.data[i].P_body.cheader.isfinished);
        printf(" %s | ", q.data[i].P_body.data);
        if (i == q.rear) {
            break;
        }
    } while (i != q.front);
//    printf("\n\n");
    return;
}

server_type.h

구조체 예시이다. 입 맛에 맞게 수정해서 사용하면 된다.

typedef struct packet Packet;
typedef struct packet_header P_header;
typedef struct packet_body P_body;
typedef union packet_convert P_convert;

typedef enum data_type
{
    command = 0,
    data = 1,
    signal =2,
    file =3,
}D_type;

struct packet_header
{
    int msgID;          //message ID
    D_type type;        //is it command or data?
    char isfinished;    //is it finished
    int seq;            //sequence
    int data_size;      //size of packet per one period

};
struct packet_body
{
    P_header cheader;
    unsigned char data[BUF_SIZE-sizeof(P_header)];
};
union packet_convert{
    P_body P_body;
    unsigned char buffer[sizeof(P_body)];
};

 

Union 개념 및 사용방법이 알고 싶다면 아래 링크에서 확인 가능하다.

2020/03/18 - [programmer/Embedded] - Union 사용 이유

 

Union 사용 이유

기본 설명 Union 은 한국말로 공용체라고 한다. 뭔가를 공용으로 사용하는 놈이라고 생각되는데 왜 Union을 사용해야 하고 어디에 쓰이는지 예시를 통해 설명하도록 하겠다. 설명은 하기 목차대로

suho413.tistory.com

 

반응형
사업자 정보 표시
라울앤알바 | 장수호 | 서울특별시 관악구 봉천로 13나길 58-10, 404호(봉천동) | 사업자 등록번호 : 363-72-00290 | TEL : 010-5790-0933 | Mail : shjang@raulnalba.com | 통신판매신고번호 : 2020-서울관악-0892호 | 사이버몰의 이용약관 바로가기