bdfgdfg

[온라인 서버] 네트워크 라이브러리 - Queue Class 본문

게임프로그래밍/서버 책

[온라인 서버] 네트워크 라이브러리 - Queue Class

marmelo12 2022. 1. 9. 16:41
반응형

Queue Class

 - 큐 자료구조는 온라인 게임 서버에서 자주 쓰이는 자료구조.

 - Queue Class도 기본적으로 큐 알고리즘을 바탕으로 Monitor클래스를 상속받아 둘 이상의 쓰레드들이 동시에 접근하지 못하도록 보호.

 

딱히 어려운게 없으므로 바로 소스코드.

#pragma once
#include "Monitor.h"

template <typename T>
class Queue : public Monitor
{
public:
	Queue(int MaxSize = MAX_QUEUESIZE);
	~Queue();
public:
	// 큐에 데이터 삽입
	bool PushQueue(T queueItem);
	// 큐의 크기 감소
	void PopQueue();
	// 큐가 비었는지 확인
	bool IsEmpty();
	//데이터 가져오기
	T GetFrontQueue();
	//큐의 현재 크기 반환
	int GetQueueSize();

	// 큐의 최대 크기를 반환
	int GetQueueMaxSize() { return m_queueMaxSize; }
	void SetQueueMaxSiz(int MaxSize) { m_queueMaxSize = MaxSize; }
	void ClearQueue();

private:
	// 실제 데이터를 저장하는 배열
	T* m_arrQueue;
	int m_queueMaxSize;
	// 동기화
	Monitor m_csQueue;

	int m_curSize;
	// 큐의 배열에 가장 마지막 데이터를 가르킴.
	int m_endMark;
	// 큐의 배열에 가장 첫번째 데이터를 가르킴.
	int m_beginMark;

};

template<typename T>
Queue<T>::Queue(int maxSize)
{
	m_arrQueue = new T[maxSize];
	m_queueMaxSize = maxSize;
	ClearQueue();
}

template<typename T>
Queue<T>::~Queue()
{
	delete[] m_arrQueue;
}

template<typename T>
bool Queue<T>::PushQueue(T queueItem)
{
	Monitor::Owner lock(m_csQueue);
	{
		if (m_curSize >= m_queueMaxSize)
			return false;

		++m_curSize;
		// endMark가 끝까지 왔다면 다시 0으로 돌려 데이터 추가.
		if (m_endMark == m_queueMaxSize)
			m_endMark = 0;
		m_arrQueue[m_endMark++] = queueItem;
	}
}

template<typename T>
void Queue<T>::PopQueue()
{
	Monitor::Owner lock(m_csQueue);
	{
		--m_curSize;
		++m_beginMark;
	}
}

template<typename T>
T Queue<T>::GetFrontQueue()
{
	Monitor::Owner lock(m_csQueue);
	{
		if (m_curSize <= 0)
			return NULL;
		if (m_beginMark == m_queueMaxSize)
			m_beginMark = 0;
		// 여기서 Pop을 처리하지는 않는다!
		return m_arrQueue[m_beginMark];
	}
}

template<typename T>
bool Queue<T>::IsEmpty()
{
	bool flag = false;
	// 인터락 아토믹.
	Monitor::Owner lock(m_csQueue);
	{
		flag = (m_curSize > 0) ? false : true;
	}
	return flag;
}

template<typename T>
int Queue<T>::GetQueueSize()
{
	int size;
	Monitor::Owner lock(m_csQueue);
	{
		size = m_curSize;
	}
	return size;
}

template<typename T>
void Queue<T>::ClearQueue()
{
	Monitor::Owner lock(m_csQueue);
	{
		m_curSize = 0;
		m_endMark = 0;
		m_beginMark = 0;
	}
}

여기서 순환 큐는 데이터를 저장,추출할 때 끝에 도달했으면 다시 처음 위치(0)으로 돌리는 작업만 단순히 하였음.

 

예제

int main()
{

    Queue<int> q;
    for (int i = 0; i < 100; ++i)
        q.PushQueue(i);

    while (!q.IsEmpty())
    {
        std::cout << q.GetFrontQueue() << std::endl;
        q.PopQueue();
    }

    return 0;

}

 

 

위 내용은 강정중님의 온라인 게임 서버 서적을 참고 하였습니다.

반응형
Comments