묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Lock-Free Stack #2 01:16쯤에 말씀하신 동시에 TryPop() 할 경우..질문입니다.
안녕하세요!동시에 TryPop() 을 할 경우, oldHead를 참조하는 스레드가 있을 수 있고 이 때 무작정 해제해버리면 use after delete 오류가 발생할 수 있다고 하셨습니다.TryDelete() 함수를 구현하실 때, 1 == popCount 안에서 delete old_head 를 할 때는 이미 분리했으니까 괜찮다고 하셨는데요. 첫 문단에서 언급한 부분과 반대되는 말을 하신 것 같다는 느낌을 받았습니다.제가 생각했을 때는, 저희 수업 때 사용하신 예제 코드에서는, cas 연산을 통해 oldHead 를 분리했기 때문에 use after delete 오류가 안 날 것 같단 생각이 들더라고요.궁금해서 테스트를 해봤습니다.TryDelete() 함수를 호출하지 않고 바로 delete old_head; 를 호출하는 코드를 넣었고요, 지금 이 질문을 올리고 있는 와중에 push() 는 sleep_for(1ms)를 주고 pop()을 하는 스레드는 5개를 돌려서, 진단 도구에서 확인되는 프로세스 메모리가 1mb이 유지되게 설정해서 30분 넘게 돌려보고 있습니다. 오류가 안 나고 있는 광경을 목격 중입니다. 그냥 운이 좋은 걸까요?오류가 발생하지 않는 이유는 다음과 같다 생각합니다.atomic 변수인 head에서 cas 연산을 하기 때문에 간발의 차이로 먼저 다음 코드를 통과한 스레드가 획득한 oldHead는 다른 스레드가 이후에 될 oldHead와 같지 않다. while 조건에서 true를 반환하는 순간 head는 head의 next를 가리키고 있게 되기 때문이다. compare_exchange_weak() 함수가 true를 반환하면 head는 원자적으로 head->next를 가리키는 상태가 된다.while (old && false == _head.compare_exchange_weak(old, old->next)) return false; 고견 부탁드립니다.멋진 강의 감사합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
강의를 듣던중에 궁금한점이 생겨서 질문드립니다.
Reader-Writer Lock 구현중에 Atomic 변수를 사용하고 있는데, Atomic 변수자체가 lock이 포함되어 있어서 대규모 Read가 병렬적으로 처리되는 상황이 아니라면 일반 lock을 사용하는 것이 더 효율이 좋을 것 같습니다.하지만 Reader-Writer Lock이 의미가 있을 정도로 대규모 Read가 빈번하게 일어나는 경우에는 WriteLock쪽에서 기아 현상이 발생할 것 같습니다.그렇다면 Reader-Writer Lock은 피크 타임에 대규모 Read가 발생하는 경우에만 사용하는 건가요?(LThreadId << 16) & WRITE_THREAD_MASK 부분에서 굳이 & 연산을 추가로 하는 이유가 뭔가요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
식별자 및 헤더 에러
2022버전인데정의는 되어있으나 특정 tcp/ip함수들을 식별하지 못하는 현상이 있습니다.(헤더가드 다 하였음)제 경우에는 inet_ntop 함수 단 하나만 컴파일러가 식별하지못하는 에러가있어서 stackoverflow나 reddit을 찾아도 원하는 상황에 및 해결법은 나오지않아pch.h환경에서 쓰기때문에 GlobalPch.h 에서#include <WinSock2.h>#include <mswsock.h>#include <ws2tcpip.h>#include <windows.h>4가지 헤더를 이 순서대로 배치하고 프로젝트 별 헤더에서는 위의 4가지를 선언하지않으니 해결되었습니다.혹시나 특정함수 단 하나만 식별되지않거나하면 시도 해보시기 바랍니다.저는 시간날렸어도 누군가는 금방 해결해서 다음step으로 빠르게 가길 빕니다.
-
미해결[켠김에 출시까지] 유니티 캐주얼 모바일 MMORPG (M2)
몬스터 AI
안녕하세요 강의 잘 보고 있습니다.현재 3d 모바일 게임을 만들고 있습니다 가상 조이스틱을 이용해 플레이어를 이동시키고 있구요현재 몬스터 AI를 구현하기 위해 A*를 이용해서 PathFinding을 구현중에 있습니다 구현을 위해 맵은 1X1단위로 위에서 아래로 Ray를 쏴서 맵 정보를 저장해 놓은 상태입니다. 이런 상황에서 만약 몬스터는 (2, 0, 2)좌표에 Target은 (5.5, 0, 5.5) 좌표에 있다면 절대 Target을 찾을 수 없겠다 싶어 거리가 1이하이면 찾은걸로 가정을 하려 했습니다 그런데 그 사이에 장애물이 있을 수도 있고 별의 별 상황이 있겠다 싶어 이게 맞는건지 의문이 듭니다 이런 그리드 단위로 움직이지 않는 게임에선 어떻게 Finding을 해야 좋을까요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
스핀 락에서 CPU 점유율 관련한 질문입니다!
안녕하세요!스핀이 계속 되면서 CPU 점유율이 치솟는 문제에 대한 대안으로 sleep_for(1ms)를 호출하는 건 어떻게 생각하실지 궁금합니다.질문을 다 하고 나니, 커널의 도움을 굳이 받지 않고 오래 대기하지 않아도 되는 상황이 보장될 때 사용하면 좋은 락이 스핀 락인데 sleep_for()을 하면 컨텍스트 스위칭이 발생하겠네요. 이렇게 되면 스핀 락을 쓰는 이유가 퇴색될 것 같다는 생각이 듭니다.고견 부탁드립니다🙏
-
미해결[켠김에 출시까지] 유니티 캐주얼 모바일 MMORPG (M2)
웹서버로 구현되는 기능들이 궁굼합니다.
안녕하세요! 선생님 강의를 거의 빠짐없이 듣고 열심히 공부하고 있는 수강생입니다. MMORPG 개발 9개 시리즈부터 번외편, M1 강의까지 2~3회씩 반복해서 수강하며, 이제는 새로 올라오는 M2 강의를 매주 주말마다 기다리고 있습니다!강의를 기다리며 채팅 기능, 길드, 파티, 우편 시스템을 직접 구현해보려고 하는데, 처음으로 강의 내용과 다른 것을 시도하다 보니 제가 제대로 하고 있는지 확신이 들지 않더라고요. 제가 생각하기에 채팅, 길드, 파티, 우편 기능은 ACCOUNT 서버처럼 WEB 서버로 구현하는 게 좋을 것 같아서, MMORPG 시리즈에서 배운 WEB 서버를 기반으로 위에 기능들을 하나씩 만들어가고 있습니다.서론이 길었네요 ㅠㅠ 궁금한 점이 있습니다! 실제 현업에서는 위에 언급한 기능들이 웹 서버로 구현되는지 아니면 게임 서버로 구현되는지 궁굼합니다!
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
소멸자 부분에서 ref 변수들을 release 하는건 좋지 못한가요?
이번 강의는 순환 참조일 때 한 객체가 소멸될 시 참조하고있는 객체에 관해 refCount가 줄지않아 문제가 생기는 것에 관해서 여러 방법을 알려주시는것 같았습니다. 그렇다면 소멸자 부분에서 자신이 참조하고 있는 객체들을 release해주는것은 어떤가요?참조하는 객체가 많으면 유지보수하기 어려울것 같은데 그래도 이것 또한 해결책이 될 수 있나요?
-
미해결[켠김에 출시까지] 유니티 캐주얼 모바일 MMORPG (M2)
C++강의 듣다가 왔습니다.
C++과 언리얼로 만드는 mmorpg 시리즈를 구매한 학생입니다. 1주차부터 이해가 안돼서찾아보니 Part3 유니티 (클라 프레임워크)Part4 게임서버 (서버 프레임워크 ServerCore)Part7 게임서버&클라 연동 (클라 서버 연동 기본기)Part8 EF Core (ORM) 를 읽어보면 이해하기 쉽다고 하셨는데part4. 게임서버는 C++강의로 들어도 괜찮을까요??
-
미해결[켠김에 출시까지] 유니티 캐주얼 모바일 MMORPG (M2)
멀티 스레드 관련 의문점
안녕하세요 강의 잘 보고 있습니다.코드를 보면서 멀티 스레드 관련해서 궁금한게 있어 질문 남깁니다.1.ClientSession에서 Lock을 잡지 않는 이유는 Receive쪽에서 하나의 스레드만 들어오기(낚시대 비유) 때문에 안걸어도 되는건가요? 즉 하나의 스레드가 메서드 안의 메서드를 타고 타고 들어와서 안전한건가요?2. 1번이 맞다면 ClientSession 에서 GameLogic Push 하는 이유는 스레드 안전성 때문이라기보단 멀티 스레드를 활용하기 위함이라 보면 될까요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
writeCount는 원자성 보장하지 않아도 되나요??
writeCount는 atomic이 아닌 일반 uint16이고writeLock++;writeLock--;같은 증감 연산자를 할 때 따로 임계구역 만들지 않는것 처럼 보입니다. 이러면 진짜 만약에 두 개 이상의 쓰레드가 동시에 증감연산을 하게될 경우 이전에 해봤던 예제처럼uint16 temp = writeLock;temp++;writeLock = temp;이렇게 3단으로 실행이 되서 조금씩 오차가 생길 수 있을것 같은데 이 부분은 따로 고려하지 않아도 충분한가요??
-
미해결[켠김에 출시까지] 유니티 캐주얼 모바일 MMORPG (M2)
포폴용으로 AWS 인스턴스 1개와 탄력적 IP 1개를 항시 켜놔도 비용이 부과될까요?
루키스님 안녕하세요? C# AWS 답변 보고 여기로 와서 클라 입장 공인 IP를 가지고 사설 IP에 접근하는 것 성공했습니다. 아침 답변 감사합니다. 제가 포트폴리오 작성 간에 데모 프로그램을 준비해보려고 하는데 (기준은 C# 파트7 수강 이후입니다) 첫 번째 방법은 클라, 서버 exe 한폴더에 넣고 .bat 파일 만들고 이거 하나만 실행시키서 서버 실행 -> 클라 실행 순으로 입장시키기 입니다. 그런데 이 방법은 .net이 안깔려 있으면 서버부터 크래시가 나길래 인사담당자나 면접관이 못볼 수도 있겠어서 찜찜해서 두 번째 방법으로 생각한건 AWS입니다. 윈도우 프리티어와 인스턴스 프리사양, 그리고 고정용 IP용 탄력적 IP를 만들어서 항시 켜놓으려고 합니다(보안 정책은 여기 강의처럼다 뚫어놓긴 합니다). 그리고 데모 프로그램은 클라이언트만 제시하는 방법을 생각 중입니다. 이 경우 AWS 서비스가 무료거나 소액이면 해볼만한 방법이라고 생각되는데 둘 중에 어느 방법이 괜찮을지 의견 여쭈고 싶어서 질문 드립니다.
-
해결됨[켠김에 출시까지] 유니티 캐주얼 모바일 MMORPG (M2)
JobTimer 클래스의 우선순위 큐 질문
안녕하세요. JobTimer 클래스에서 사용된 우선순위 큐 관련해서 2가지 궁금한 점이 있습니다.1. 여기서 사용된 우선순위 큐는 최소힙으로 구현된게 맞나요?PriorityQueue.cs 에 작성된 우선순위 큐는 최대힙 이지만, JobTimerElem 구조체를 정의할 때 CompareTo 메서드를 오버라이딩 해서 최소힙을 사용하게끔 수정한 것으로 이해했는데 제대로 이해한게 맞을까요?2. Pop 메서드에서 힙 정렬 과정 질문 PriorityQueue.cs에 작성된 Pop 메서드의 While 문이 힙 정렬을 담당하는 부분으로 이해했습니다.만약 While 문 한 번으로 정렬이 끝나지 않는 경우는 어떡하나요?예를 들어 다음과 같이 저장된 최소 힙의 경우이렇게 While문이 한 번 끝났는데 최솟값인 2가 루트 위치에 있지 않은 경우가 있어서 질문 드립니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
static TypeConversion conversion, template argument 없는 경우
준비해주신 강의자료TypeCast.h153번줄에 있는 선언에 대한 질문입니다. static inline bool CanConvert(int32 from, int32 to){static TypeConversion conversion;return s_convert[from][to];} CanConvert 함수안에 있는 TypeConversion 타입의정적변수 선언이 문법적으로 잘 이해가 가지 않습니다 TypeConversion은 class template이기 때문에선언할 때 template argument값(=typeList)을 줘야 한다고 생각했습니다.(제가 생각했던 예시)ex) static TypeConversion<TL> conversion; 근데 예시 코드에는 생략하여도 잘 동작해서관련해서 어떤 문법인지 찾으려고 했는데 찾지 못했습니다 개인적으로 열심히 고민해봤는데 default type이 정해진 경우에 생략이 가능하고template function에는 인자 값을 통해 추론해템플릿 인자값을 생략하는 경우도 있었지만둘 다 해당하지 않는 것 같습니다 TypeConversion<TL>::CanConvert(ptr->_typeId, IndexOf<TL, remove_pointer_t<To>>::value)를 통해서 이미 template class가 인자 값을 받아서인스턴트화 했기 때문에 생략이 가능한 것으로 이해해도 괜찮을까요? -수정Injected-class-name 라는 cpp reference를 찾았습니다제가 궁굼해 하는게 이게 맞을까요?
-
해결됨[켠김에 출시까지] 유니티 캐주얼 모바일 MMORPG (M2)
마우스 오른쪽 버튼 및 키보드 입력이 받아지지 않습니다.
안녕하세요.강의에서 제공되는 코드를 수정하며 만들고 싶은 게임을 만들려고 하는데요 롤과 유사한 조작 방식으로 만들고 싶은데 마우스 오른쪽 버튼이랑 키보드 입력이 안 받아지네요.정말 아무것도 수정안하고 MyHero.cs 에서 Input.GetMouseButton(0) 요 부분을 0에서 1로 바꾸기만 해도 아무런 동작이 되질 않습니다. 모바일용 프로젝트라 마우스 오른쪽 버튼 및 키보드 입력이 받아지지 않는 건가 의심이 되어 빌드 세팅을 확인해 보니 빌드 세팅은 또 PC로 되어있어서 알쏭달쏭한 상황입니다. 어떤 부분을 수정하면 좋을까요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Event와 Condition Variable 중에 헷갈리는 부분이 있어서 질문드립니다
안녕하세요 선생님. 이전 강의인 Event와 비교했을 때 헷갈리는 부분이 있어서 질문 드립니다. EventEvent를 사용하면 Lock코드와 묶여있지 않기 때문에 Producer 쓰레드가 연달아 Lock을 가져가게 될 경우에 q의 값이 누적되어 값이 틀어질 수 있다고 하셨던 것으로 이해했습니다.아래는 Event 강의의 코드인데요, Consumer 함수에서 if(!q.empty())를 while(!q.empty())로 변경했을 때 q의 크기가 4자릿수로 넘어가는 경우는 발생하지 않는 반면에, 조건변수를 사용하면 q의 크기가 4자릿수가 넘어갈 때가 심심찮게 발생합니다. CPU사용량은 거의 비슷합니다.강의 설명에서는 Kernel Object와 User-Level Object의 차이때문에 Event보다 조건변수를 사용하는 것이 효율적이라는 뉘앙스로 느껴집니다. 물론, 이전 가르침을 통해서 상황에 따라 효율적인 방식은 전부 다르겠지만, 이번의 경우는 예외처럼 느껴져서 질문드립니다. 조건변수가 더 효율적인 방식인가요?#include "pch.h" #include <iostream> #include "CorePch.h" #include <thread> #include <atomic> #include <mutex> #include <windows.h> mutex m; queue<int32> q; HANDLE handle; void Producer() { while (true) { { unique_lock<mutex> lock(m); q.push(100); } ::SetEvent(handle); this_thread::sleep_for(100ms); } } void Consumer() { // 데이터를 꺼내 쓰고 있음 while (true) { ::WaitForSingleObject(handle, INFINITE); // 현재 상태가 ManualReset이면 수동으로 Non-Signal로 바꿔줘야 함. //::ResetEvent(handle); unique_lock<mutex> lock(m); if (!q.empty()) { int32 data = q.front(); q.pop(); cout << data << '\n'; } } } int main() { handle = ::CreateEvent(NULL/*보안속성*/, FALSE/*bManualReset*/, FALSE/*bInitialState*/, NULL); thread t1(Producer); thread t2(Consumer); t1.join(); t2.join(); ::CloseHandle(handle); }
-
해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
이벤트를 쓰는 것이 CPU 처리율이 더 높게 나오는데 무엇이 문제인지 모르겠습니다
안녕하세요 선생님 🙂 선생님 강의 덕분에 서버에 입문을 수월하게 한 것 같습니다. 감사합니다 ^^ 다름이 아니라, 이벤트를 쓰면 WaitForSingleObject 함수로 인해서 계속해서 대기가 되는 상태일텐데 CPU 점유율이 쓸데없이 무한루프를 도는 것보다 많이 먹습니다. 무엇이 문제인지 잘 모르겠습니다 ㅠㅠ 확인해주시면 감사하겠습니다!!<이벤트 사용X> <이벤트 사용O>
-
해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
몬스터 충돌판정
안녕하세요 강의를 보고 배운 서버와 dx11로 3d게임을 만들어 보고있습니다. 이동동기화 등은 잘 됬고 몬스터를 만들었는데 접속한 클라에서 모두 동일하게 로직이 돌아가야하니 몬스터의 로직은 서버에서 돌아가게 만들었습니다. 그런데 플레이어가 몬스터를 타격하면 타격한 플레이어가 타격했다는 패킷을 보내고 플레이어가 플레이어를 타격하면 피격당한 플레이어가 패킷을 보내는 식으로 했는데 투사체 같은경우 몬스터가 투사체를 맞았다 라는건 서버에서도 충돌체를 두고 몬스터가 검증을 해야할까요? 클라에서 판단하더라도 그러면 여러 클라가 있을경우 여러 클라가 다 맞았다는 패킷을 보낼것 같아 뇌가 꼬입니다...물론 방법이야 많겠지만 이부분 구현에 있어 감이 안잡혀 질문드립니다 ㅠㅠ
-
미해결[켠김에 출시까지] 유니티 방치형 키우기 게임 (M1 + T2)
typeof 와 GetType
DataTransformer.cs 에서ParseExcelDataToList 함수 안에 typeof와 GetType을 혼용해서 사용하시는 것을 보고 궁금해서 찾아보다가 질문드립니다. typeof의 경우에 컴파일 타임에 형식의 메타 데이터를 참고해서 Type 형식을 뱉어주고GetType의 경우에 인스턴스의 형식을 런타임에 가져오는 경우 사용하는 걸로 알고 있는데요.위 함수에서 typeof(LoaderData)를 통해 Type을 가져오더라구요. 이 경우에 제네릭 타입 매개변수는 컴파일 시점에 정확한 형식을 모르기 때문에 GetType을 사용하는 것이 적절하지 않을까요?
-
미해결[켠김에 출시까지] 유니티 방치형 키우기 게임 (M1 + T2)
섹션2 - Tilemap 강의에서 BaseMap 프리팹에 Front_01 용도가 궁금합니다.
섹션2 - Tilemap 강의에서 BaseMap 프리팹에 Front_01은 어떤 이유로 필요한건지 알 수 있을까요?Front_01 온/오프를 해봐도 큰 변화는 보이지 않아서관리의 목적이나 개발의 용이성등의 이유가 있을 것 같은데궁금합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
memoryPool class관련 질문입니다,.
지금 영상을 보며 클론코딩중에 다소 이해가 안되는 부분이 있어 질문드립니다. MemoryPool::Pop()에서 header == nullptr 인 경우에할당해주는 mem 크기가 _allocSize로 되어 있는데 이 경우 MemoryHeader의 크기까지 반영해야 하는게 아닌지 질문드립니다. header = reinterpret_cast<MemoryHeader*>(::malloc(sizeof(MemoryHeader) + _allocSize));위에 코드처럼 수정을 해야 반환된 heaer가 이후에 MemoryClass에서 AttachHeader를 해줄때 MemoryHeader 크기만큼 포인터 이동이 가능해지는게 아닌가 생각합니다.