월 66,000원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Job큐를 실행하는 스레드 질문있습니다.
Job을 Pop해서 실행하는 스레드는 1개인데 Job을 만들어서 Push하는 스레드는 여러개인것으로 보이는데 이렇게 하면 결국 Job이 가득 차서 실행이 밀릴것 같은데 어떻게 하나요?
- 해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
리눅스에서 이벤트 사용
쓰레드 강의파트에서 리눅스 영역을 고려해 <windows.h>를 사용하지 않고 <thread>를 사용한다고 하셨는데 이벤트는 <windows.h> 헤더를 대체할만 것이 있을까요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
스트레스 테스트를 해봤는데 이 방식이 맞나요?
위에 사진이 서버, 아래 사진이 클라입니다. 서버가 MaxSessionCount를 3천개, 클라는 1만개 들고있습니다. 동작은 클라가 0.1초마다 채팅패킷을 날리는 형태입니다. 채팅패킷은 단순히 string 변수 하나만 보내줍니다. 딱 클라 1만개까지 정상적으로 동작하고 1만2천개부터는 제 노트북이 못버텨주는데, 이러면 제 서버는 최소 동접자 1만 이상을 수용할수 있는 서버다 라고 말할수 있는건가요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
언리얼 클라이언트 네트워크 구현시 액터의 라이프사이클
안녕하세요 루키스님 언리얼쪽에 클라이언트 네트워크 시스템을 구죽해놓았는데 마지막 관문이 풀리지 않아 질문드립니다. 확장성을 고려해 TCP 연결을 subsystem에서 중앙관리해서 여러 서버의 TCP연결을 가능하게 하려고 합니다. 일단 구현은 Subsystem에서 FTickableGameObject를 상속받아서 subsystem에서 Tick을 할수 있게 했는데요, 이렇게 하니 Tick함수에서 Recv한 패킷을 뺴오는 갱신 주기를 각각의 TCP연결마다 따로 설정할 수 없는 부분이 있습니다. 그래서 subsystem에 Actor를 각각 달아서 갱신주기를 따로 설정할수 있지 않을까 구상했는데, 액터는 레벨이 바뀔때 Actor의 생명주기가 끝나버리는 문제점이 있는데, Subsystem이 관리하고 있는 Actor가 레벨이 바뀌어도 살아남게하는 방법이 있을까요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
신규 강의 질문
안녕하세요 루키스님! 유튜브에 온라인 출판사 영상을 보고 궁금하게 생겨서 이렇게 질문드려요! 유튜브 영상에서는 WinAPI-D2D-D3D 커리큘럼, UE 커리큘럼, Unity 커리큘럼 이렇게 3개를 구상중이라고 하셨는데 C++ IOCP + UE5 연동 강의는 일정이 어떻게 되는지 알 수 있을까요? ㅠㅠ
- 해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
강의 질문
방금 알림떠서 헐레벌떡 선생님꺼 유튜브보고 왔습니다 이게 질문인지 부탁인지 말하는 입장에서도 굉장히 애매하네요 애초에 이 강의를 한 번만 볼 생각으로 보는건 아니지만 평소에 드는 생각이 강의 끝날 때쯤에 한 번씩 복기?하는 식으로 정리해주시는게 생각보다 머릿 속에 굉장히 강렬하게 남더라구요 예를 들면, 이번에 그 제가 본게 protobuf 전에 있는 패킷 부분인데요 flatbuffers하고 protobuf 차이점 / 가변 데이터 넣는 3가지 방법도 마지막에 여러 번 강조해주셔서 메모를 하지 않을 정도로 잘 남는 것 같아요 (결국 사람인지라 잊어버릴까봐 메모했습니다) 그래서 다음에 만드는 강의도 끝날 때마다 복기해주셨으면 좋겠습니당
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
lock free에 대해서 잘 이해가 가지 않습니다
lock free는 단순하게 "lock을 사용하지 않는다." 정도로만 알고 있는 상태입니다. 그런데 코드를 보니까 compare_exchange_weak 를 사용하고 이 코드가 스핀락과 상당히 유사하단 생각이 들었는데"스핀락은 lock아닌가? 그럼 lock free가 아닌게 아닌가?" 하는 생각이 들더라구요. 제가 잘못 이해한건가요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
생각을 해봤는데 이해가 잘 되지않습니다. 질문 드립니다
안녕하세요. 지금 ReadLock WriteLock 강의듣고 혼자서 구현해보는 연습중에 궁금한점이 있어서 문의드립니다. Main부분에서 for (int i = 0; i < 2; i++) { threaManger->Luncher(ThreadWrite); } for (int i = 0; i < 5; i++) { threaManger->Luncher(ThreadRead); } 고유 스레드 아이디를 부여해서스레드 2개는 Write("스레드 아이디" 1,2)스레드 5개는 Read ("스레드 아이디" 3,4,5)일을 시키는데이렇게 되면 Read만 하는 스레드는 ReadLock만 잡고Write만 하는 스레드는 WirteLock만 잡게 되어서1번 아이디의 스레드(Write)가 Read Lock을 잡을 수 없지 않나요?아래 코드에서 Readlock 함수를 보면WRITE_THREAD_MASK를 씌어서 threadId를 비교하는데 이 부분은 실행 안될 거라고 생각되는데 맞나요?실제로 디버그에서 ReadLock에 포인트를 잡고 봤는데 브레이크 포인트에 걸리지는 않았습니다.제가 궁금한 걸 글로 쓰려니 잘 정리가 안돼서 죄송합니다.질문을 요약하자면1.ReadLock을 잡는 스레드의 id는 WriteLock을 잡는 스레드 id와 똑같을 수가 있나요? // ReadLock const int lockThreadId = (_lockFlag.load() & WRITE_THREAD_MASK) >> 16; if (lockThreadId == SharedThreadId) { _lockFlag.fetch_add(1); return; } // WriteLock const int lockThreadId = (_lockFlag & WRITE_THREAD_MASK) >> 16; if (lockThreadId == SharedThreadId) { _writeCount++; return; }
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
pushOnly 인자를 주는 이유
JobQueue::Push 에서 pushOnly를 추가해야 하는 이유를 잘 모르겠습니다. JobQueue::Push 함수가 실행되었다는 것은 이미 예약한 시간이 되어서 실행되어도 좋은 Job이 JobQueue에 Push된다는 뜻이 아닌가요? 지금 당장 실행되어도 좋은 Job을 Push 하려는데, 왜 굳이 JobQueue::Execute를 건너뛰고 GlobalQueue::Push를 호출해서 한 타이밍 늦게 Job을 실행시키는지 잘 모르겠습니다.
- 해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
하나의 쓰레드에만 일감이 몰리는 현상이 왜 안좋은가요?
하나의 쓰레드가 여러 개의 JobQueue를 점유하는 현상이 안좋은 이유는 알겠습니다. 다른 쓰레드가 다른 JobQueue의 Job들을 처리하지 못하게 되니까요. 그런데 모든 쓰레드가 모든 일감을 처리할 수 있는 만능 일꾼이 된 상황에서, 하나의 쓰레드가 하나의 JobQueue를 오래동안 잡고있는 현상이 왜 안좋은지는 잘 이해가 안갑니다. 어차피 하나의 쓰레드가 붙잡고 해야할 일이 아닌가요? 동시에 여러 쓰레드가 처리 가능한 것도 아닌 것 같구요... 예를 들어, 쓰레드 A, B, C가 있다고 해봅시다. 쓰레드 A가 JobQueue 'ㄱ'를 점유하고 계속 작업을 하고 있습니다. 쓰레드 B와 C는 'ㄱ'과 관련된 일은 모두 A에게 몰아주고 나머지 작업들을 처리하고 있습니다. 그런데 A의 'ㄱ'점유가 너무 길어져서 'ㄱ'의 점유를 B에게 넘겨주었습니다. 그리고 A는 B와 C가 하던 것 처럼 나머지 작업들을 처리하게 되었습니다. 그럼 결국 'ㄱ'의 점유가 A에서 B로 넘어갔을 뿐 달라진 것이 없지 않나요? 오히려 쓸 데 없는 스위칭 비용만 발생한 것이 아닌가요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
디버그 실행시 에러발생
수업자료로 올려두신 소스코드를 받아서 실행을 해보았는데 실행중 에러가 발생하고 있습니다. 왜 강의처럼 깔끔하게 실행되지 않는걸까요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
메모리풀을 많이 만들어 놓는 이유가 있나요?
32Byte 메모리 풀과 128Byte 메모리풀 등을 많이 만들어 놓고, poolTable로 접근할 수 있게 해주었는데, 굳이 이렇게 많이 만들어 줄 필요가 있나요? 예를 들어 어차피 32바이트 메모리 풀 하나에서 32바이트 메모리 공간 여러개를 관리하는 데, 다른 32바이트 메모리 풀이 왜 더 많이 필요한 지 잘 모르겠습니다.
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
xnew vs new
안녕하세요! 강의 잘 듣고 있습니다. 강의를 듣다가 궁금한 점이 있는데요. 혹시 여기서 만든 xnew가 있는데, new 연산자와 성능차이가 있나요? xdelete와 delete도 마찬가지로 궁금합니다. 만약에 그렇다면 디버그모드에 대한 조건문을 두어서 new/delete 연산자를 관리하려고 합니다.
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
궁금한점 질문
void Push(const T& value) { Node* node = new Node(value); node->next = _head; while (_head.compare_exchange_weak(node->next, node) == false) { } } bool TryPop(T& value) { Node* oldHead = _head; while (oldHead && _head.compare_exchange_weak(oldHead, oldHead->next) == false) { } if (oldHead == nullptr) return false; value = oldHead->data; return true; } 안녕하세요 질문이 있습니다. 위의 코드에서 예를들어 t1 스레드가 Push를 하고 t2 스레드가 TryPop을 한다고 가정하면 push 에서도 _head를 참조하고 tryPop에서도 _head를 참조하니깐 TryPop에서 참조하고있는 popCount와 pendingList를 구해서 LockFree한다고 해도 운이 안좋아서 TryPop에서 _head를 메모리 할당 해제 해버리고 Push할때 그 할당 해제된 head로 node->next에 값을 대입하면 문제가 되지않나요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
가시성과 코드 재배치에 관해서 문의드립니다.
안녕하세요. 강사님... 멀티스레드 부분에서 나오는 개념이 어려워 나름의 생각 정리 후 맞는지 확인차 질의드립니다. 1) 동일한 객체에 대해 동일한 수정 순서를 보장한다. 만약 공유자원 A에 스레드 1, 2, 3이 지속적으로 접근 한다고 할 때(Producer 처럼 while(true) { ... } 구조) 특정 시점에 스레드 1이 A에 저장된 값을 읽었고 바로 스레드 2가 A에 저장된 값을 읽었다면 스레드 2가 공유자원 A에서 읽은 값은 적어도 스레드 1이 공유자원 A에서 읽은 값을 포함하여 이후 시점에 변경된 값이 읽혀진다. 2) 코드 재배치 - 코드 재배치는 Cache에 의한 재배치, CPU 파이프라인에 의한 재배치가 있다. -> 단일 스레드에서는 코드 재배치가 이루어져도 절차에 맞게 결과가 나왔지만, 멀티스레드일때는 코드 재배치에 의해 원하는 결과가 나오지 않을 수 있다. 3) 가시성 보장이란 - 스레드 1에서 공유 자원에 대한 값을 변경하고, 바로 스레드 2가 공유 자원에 대한 값을 읽었을 때 스레드 1에서 변경한 값이 읽혀지는 것 (스레드 1의 캐시에서 메모리에 값을 반영한 것) 4) lock_guard<mutex> lock(m); - 해당 코드도 결국에는 단일 스레드에서 동작하는 것 과 동일하기에 원자성을 보장한다고 보아야 되는 것 인지요 ?... 원자성을 보장한다면 동일 객체에 대한 수정 순서를 보장한다고 보면 되는 것이 맞는지 궁금합니다. (코드 재배치 문제는 별 문제가 안될 거 같지만, 가시성은 보장하는지도 궁금해요 ㅠㅠ) 이정도로 해석해도 되는 부분인지요 ..
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
forward 식별자를 찾을 수 없다는 에러가 발생합니다.
루키스님의 강의자료를 다운받아서 xalloc, xrelease 부분 이름을 바꾸고 컴파일을 진행하는데 저렇게 에러가 발생합니다. 이건 어떤 이유에서일까요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
recv buffer 관련하여.
안녕하세요 루키스님 좋은 강의 감사드립니다. 다름이 아니라, iocp 로 서버를 만드는 도중, http 와 연동되는 간단한 서버를 만들고 있습니다. 코드에서 보이다 싶이 RegisterRecv() 로 등록 시켜주고, 같은 Event 가 RECV 일시, 처리를 진행하게 되는데, 문제는 http Request 의 크기가 특정 버퍼보다 크게 된다면, RegisterRecv ( ) 를 걸어도 버퍼가 안읽히는 겁니다. 이럴때는 어떻게 해야 하나요 ? 그리고 다시 창을 로드했을때, (예를 들어 localhost:port 를 브라우저로 로드) 하면, 잘리고 난 그 뒤의 버퍼가 나옵니다.. - wsaBuf.buf 의 크기보다 큰 데이터가 왔을때, 따로 설정해주어야 하는 값이 있나요..?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
SendBuffer 락 관련 질문입니다.
안녕하세요 루키스 선생님 강의 관련되어 몇가지 질문 사항이 있어 문의드립니다. 1. WSASend 같은 경우 스레드 경합이 일어나 큐에 담아 처리하셨는데 몬스터 사냥이나 채팅이 원인이라고 하셨습니다, 하나의 세션에 이와 같이 스레드 경합 이벤트가 어떻게 동시에 일어날 수 있는지 궁금합니다. (보통 채팅을 치면서 사냥을 하진 않아 잘 이해가 안갔습니다.) 2. 극히 비효율 적이라도 Send 버퍼 자체를 함수 내에서 선언하여 보내게 되면 별도의 락 과정 없이 Send 하여도 Thread Safe 한지 궁금합니다. 지역변수는 스택 영역이라 스레드별로 따로 있다고 알고 있어 문의드립니다.
- 해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
일정길이 이상 string 전송시 서버가 죽습니다
배열이나 포인터 전송시 Reserve 해야하는게 귀찮아서 바로 string으로 전송했더니 일정길이 까지는 잘 동작 하더라구여. 근데 한 20글자 넘어가면 수신할때 BufferReader 쪽에서 에러를 뱉어냅니다. (물론 read, write 순서 맞춰주었습니다.대략 15자까지는 정상 동작합니다) 혹시 현 구조에선 std::string 일정 길이 이상은 소화(?)를 못시키나요? 네트워크 환경에선 std::string을 쓰는게 많이 별론가요?
- 해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Receive 에 관해 질문 드립니다.
안녕하세요. 정말 신입 서버의 교과서 같은 강의라서 잘 보고 있다가 문득 궁금한 점이 생겨 질문 드리게 되었습니다. 제가 이해하기로는 TCP 는 Stream 방식이라서 100 byte 의 데이터를 send 하는 경우, 한 번에 받는다는 보장이 없어 20, 30, 50 이렇게 끊어서 받는 경우가 충분히 있을 것 같은데.. 현재 강의해서 제작된 RecvBuffer 를 사용함과는 무관하게 해당 현상을 해소하는 부분이 아직 안 보이는 것 같은데 이 부분은 따로 처리를 해야되는 부분인가요? 추후에 OnRecevie 함수 내부에서 처리를 하게끔 만드는 것인지, 아니면 해당 현상에 관련된 작업은 굳이 안해도 되는 것인지 궁금하여 질문드려봅니다.