목록Categories (1099)
KoreanFoodie's Study
[C++ 게임 서버] 2-5. STL Allocator 핵심 : 1. STL 자료구조에서 사용하는 allocator 대신, 우리가 직접 만든 STL Allocator 를 적용한 커스텀 STL 을 만들어 보자. 2. STL Allocator 는 allocate 와 deallocate 함수만 정의해 주면 되며, STL 특수화에서 Allocator 의 인자를 우리가 만든 STL Allocator 로 바꿔치기해주기만 하면 된다! 우리는 지난 시간에 Stomp Allocator 를 구현하면서, 메모리 할당/해제를 커스터마이징 할 수 있다는 것을 알게 되었다. 그리고 한 발 더 나아가서, 사실 STL 자료구조(vector, queue 등)을 이용할 때도, 우리가 직접 만든 allocator 를 사용할 수 있다! 이..
[C++ 게임 서버] 2-4. StompAllocator 핵심 : 1. 프로그램은 가상 메모리를 사용하므로, 메모리 오염이 즉각적으로 발견되지 않을 수도 있다. 2. StompAllocator 를 사용하면, 할당 및 해제 시 '실제로' 메모리의 할당과 해제가 일어나므로, 메모리 오염으로 인한 문제를 즉각적으로 발견할 수 있다(alloc 은 '예약' 상태밖에 사용안함). 3. PageSize 와 Granularity 등의 개념을 잘 알아두자. 일반적으로 기본 PAGE_SIZE 는 4KB, Granularity 는 64KB 이다. 이전에 언리얼 엔진과 관련된 테스트를 진행할 때, UnrealVS 를 이용해 '-stompmalloc' 테스트를 하는 내용을 포스팅한 적이 있었다. StompAllocator 를 ..
[C++ 게임 서버] 2-3. Allocator 핵심 : 1. C++ 에서는 new 와 delete 도 오버로딩할 수 있는데, Allocator 를 만들어 커스텀화된 new 와 delete 를 사용해 보자! 2. placement new 기법을 이용하면, 내가 지정한 메모리에 객체를 초기화할 수 있다! 놀랍게도(?) C++ 에서는 new 와 delete 를 오버로딩하여, 메모리 관리를 섬세하게 커스터마이징할 수 있다. static void* operator new(size_t size) { cout
[C++ 게임 서버] 2-2. 스마트 포인터 핵심 : 1. 스마트 포인터에는 3종류가 있다. unique_ptr, shared_ptr, weak_ptr. 이 중, unique_ptr 는 소유권 개념을 위한 간단하고 가벼운 스마트 포인터이다. 2. shared_ptr 를 생성하면 사용하고자 하는 타입에 대한 메모리와 참조 카운트 등을 관리하는 제어 블록(Control Block)에 대한 메모리가 둘 다 할당된다. shared_ptr 의 경우 순환 문제가 발생할 수 있으므로, 주의해야 한다! 3. shared_ptr 에 대한 참조 횟수가 사라지면 우리가 사용하고자 하는 데이터에 대한 메모리는 해제되나, 만약 해당 포인터를 참조하는 weak_ptr 가 있을 경우, 제어 블록은 해당 포인터를 참조하는 weak_..
[C++ 게임 서버] 1-25. Reference Counting 핵심 : 1. 멀티 쓰레드 환경에서, 생 포인터를 사용하는 것은 언제나 위험하다. 의도치 않게 delete 된 포인터를 사용하려고 할 수도 있기 때문이다. 2. 일반적으로는 Smart Pointer 를 통해 이런 문제를 해결하는데, 핵심적인 부분은 결국 Reference Count 를 체크하여 nullptr 에 접근하는 것을 막는 것이다! 물론 SharedPtr 까지 제대로 써 주어야 문제를 막을 수 있다. 멀티쓰레드 프로그래밍을 할 때, 생 포인터를 사용하게 되면 의도치 않게 nullptr 에 접근하는 경우를 맞딱뜨리게 된다. 아래의 예시를 보자. 레이스와 터렛이 있다고 하고, 터렛이 레이스를 타겟팅하여 격추 시키는 것을 상상해 보자! ..
[C++ 게임 서버] 1-24. 연습문제 (소수의 갯수 구하기) 핵심 : 1. 연습문제를 풀어보자... (주어진 숫자까지의 소수의 갯수 구하기) 2. 쓰레드 혹은, future 를 통해 구현할 수 있다. 3. thread::hardware_concurrency() 를 이용해, 실제 코어 갯수만큼 쓰레드를 생성하는 것이 더 효율적일 수 있다(그보다 훨씬 많이 생성하는 것보다). 이제 연습문제를 풀어보자. 주어진 숫자에 대해, 1부터 해당 숫자까지 소수의 갯수를 구하는 문제이다. 일단 멀티 쓰레드를 이용할 것이니, 각 쓰레드에 태워 보낼 함수를 다음과 같이 정의하자 : bool IsPrime(int InInput) { if (InInput
[C++ 게임 서버] 1-23. DeadLock 탐지 핵심 : 1. 데드락을 잡는다는 것은, 결국 락을 잡는 방식에 있어 사이클이 형성되는지를 판단하는 것과 동일하다. 2. DFS 를 응용하여, 사이클이 생기는지 여부를 검사하면 DeadLock 상황을 미리 검출할 수 있다. DeadLock 의 경우, 개발 단계에서는 나오지 않으나, 막상 라이브 서비스를 하면 검출되는 경우가 많다. 구조적으로는 데드락이 걸릴 로직이 있음에도, 접속자 수가 많지 않아 데드락이 걸리지 않을 수 있다. 이런 타이밍 적인 이슈에 의존하지 않고, DFS 방식으로 사이클이 있는지를 검사하여, 데드락 문제를 미리 방지할 수 있다. 데드락을 잡는다는 것은, 결국 락을 잡는 방식에 있어 사이클이 형성되는지를 판단하는 것과 동일하기 때문이..
[C++ 게임 서버] 1-22. Reader-Writer Lock 핵심 : 1. 읽는 경우가 쓰는 경우보다 훨씬 많을 경우, Read Lock 과 Write Lock 을 나누어서 사용할 수도 있다. 2. Write Lock 의 경우 쓰레드의 ID 를 기준으로 소유권을 경합하고, Read Lock 의 경우 공유 카운트를 올리는 방식으로 작동한다. 3. Write Lock 을 잡은 상태에서 Read Lock 을 잡는 것은 가능하지만, Read Lock 을 잡은 상태에서 바로 Write Lock 을 잡는 것은 불가능하도록 설계한다. 만약 어떤 컨텐츠에서, 내용을 읽는 경우는 1초에 100번 일어나는데, 실제로 내용을 쓰는 경우는 일주일에 한 번 일어난다고 가정해 보자. 이때, 사실 내용을 읽을 때마다 쓰레드별..
[C++ 게임 서버] 1-21. ThreadManager 핵심 : 1. Thread 를 직접 생성하기보다, ThreadManager 를 통해 생성해 보자. 2. ThreadManager 를 통해 쓰레드를 관리하면, 초기화 및 종료 시점의 작업을 자동화시킬 수 있을 것이다. 3. CRASH 관련 매크로를 유용하게 활용하자. 이제 본격적으로 서버 구축을 시작하기 전에, Thread 관리를 도와줄 ThreadManager 를 만들어 보도록 하겠다. 원리나 기능은 간단하다. 현재로서는 Thread Local Storage 에 각 쓰레드별로 ID 를 부여하고, 생성시에 이를 출력하는 정도의 기능만 만들 것이다. 코드를 보면 이해가 빠르다. ThreadManager.h #pragma once #include #in..
보호되어 있는 글입니다.