오브젝트풀은 소프트웨어 개발에서 성능 최적화를 위해 사용되는 디자인 패턴이다.
객체 생성과 소멸에 드는 비용을 줄이기 위해 미리 생성된 객체들을 풀(Pool)에 보관하고 재사용하는 방식이다.
📌 핵심 개념
ObjectPool의 기본 아이디어는 비용이 많이 드는 객체들을 필요할 때마다 새로 생성하지 않고, 미리 생성해두고 재사용하는 것이다. 객체를 사용한 후에는 다시 풀로 반환하여 다른 곳에서 재사용할 수 있게 한다.
📌 동작 원리
- 초기화: 풀 생성 시 일정 수의 객체를 미리 생성하여 풀에 저장
- 대여(Rent): 객체를 요청하면 풀에서 사용 가능한 객체를 제공
- 반환(Return): 사용이 끝난 객체를 다시 풀로 반환
- 재사용: 반환된 객체는 초기화된 후 다른 요청에서 재사용
앞서 작업하던 채팅서버에서 Packet을 오브젝트풀을 사용해 할당하려고한다.
Packet은 멀티스레드에서 사용해야하기 때문에 앞서 포스팅한 Lock-free Stack을 이용해 오브젝트 풀을 구현했다.
Alloc 함수
template<class DATA>
DATA* ObjectPool<DATA>::Alloc(void)
{
Node* AllocNode;
CheckNode Top;
int AllocCount = _AllocCount;
int UseCount = _UseCount;
InterlockedIncrement(&_UseCount);
if (AllocCount > _UseCount) //사용 할 수 있는 블럭이 있는 경우
{
LONG64 LockFreeCheckCount = InterlockedIncrement64(&_LockFreeCheckCount);
do
{
Top.NodeCheckValue = _TopNode->NodeCheckValue;
Top.TopNode = _TopNode->TopNode;
AllocNode = Top.TopNode;
} while (!InterlockedCompareExchange128((volatile LONG64*)_TopNode, LockFreeCheckCount, (LONG64)_TopNode->TopNode->NextBlock, (LONG64*)&Top));
new (AllocNode) DATA;
}
else //사용 할 수 있는 블럭이 없을 경우
{
//새로운 노드 할당해주고 생성자 호출 후 넘겨줌
AllocNode = (Node*)malloc(sizeof(Node));
memset(AllocNode, 0, sizeof(Node));
new (AllocNode) DATA;
/*
할당 수와 사용 수를 늘려준다.
*/
InterlockedIncrement(&_AllocCount);
}
return (DATA*)&AllocNode->Data;
}
AllocCount와 UseCount를 비교해서 새로 할당해주거나 Stack으로 관리하는 데이터를 하나꺼내서 반환한다.
Free 함수
template<class DATA>
bool ObjectPool<DATA>::Free(DATA* Data)
{
/*
받은 데이터를 풀에 넣기 ( Push )
*/
CheckNode Top;
Node* FreeNode = (Node*)Data;
do
{
Top.NodeCheckValue = _TopNode->NodeCheckValue;
Top.TopNode = _TopNode->TopNode;
FreeNode->NextBlock = Top.TopNode;
} while (!InterlockedCompareExchange128((volatile LONG64*)_TopNode, Top.NodeCheckValue, (LONG64)FreeNode, (LONG64*)&Top));
InterlockedDecrement(&_UseCount);
return true;
}
사용완료한 데이터를 풀에 넣는다.
'언어 > C' 카테고리의 다른 글
[C] 메모리풀(Memory Pool ) (0) | 2025.06.14 |
---|---|
[C] Lock-free Stack (0) | 2025.06.14 |
[C] Lock-free 알고리즘 (0) | 2025.06.13 |
[C] TLS ( Thread Local Storage ) - 스레드 지역 저장소 (0) | 2025.06.13 |
[C] HANDLE 닫고 NULL 넣는 이유 (0) | 2025.06.02 |