통신을 위한 메시지 큐나 순환되는 큐 구조를 만들고 싶을 때 원형 큐를 많이 사용한다. 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 사용 이유
반응형
사업자 정보 표시
라울앤알바 | 장수호 | 서울특별시 관악구 봉천로 13나길 58-10, 404호(봉천동) | 사업자 등록번호 : 363-72-00290 | TEL : 010-5790-0933 | Mail : shjang@raulnalba.com | 통신판매신고번호 : 2020-서울관악-0892호 | 사이버몰의 이용약관 바로가기
'programmer > Programming' 카테고리의 다른 글
함수 포인터 사용 예 (0) | 2020.10.22 |
---|---|
Pthread 개념 및 예제 (0) | 2020.10.21 |
C 언어 Bit field 배열- 최소 메모리로 flag 저장하기 (0) | 2020.06.23 |