묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
데드락 어떻게 해결할 지 궁금합니다.
안녕하세요. Rookiss 강사님.덕분에 강의 아주 감사히 잘 들어가며 배우고 있습니다.다름이 아니라, 강의 중, 데드락 프로파일러를 이용하여, lock 간 사이클 여부를 확인하여사전에 어느 정도 사전에 예방 가능하지만 그래도 다 막을 수는 없다고 하셨는데,막상 발견된다면 데드락을 해결하는 것은 어렵지 않다고 알려주셨습니다. 혹시, 데드락 프로파일러를 통해 발견되지 않을 경우,데드락이 발생했는지 어떻게 확인하고, 데드락이 발견되면 어떻게 해결하는 지 궁금합니다. 스스로 생각하기로는 스핀락의 경우, 데드락이 발생하게 되면 뺑뺑이를 계속 돌게 될테니CPU가 증가하는 모습으로 나타날 것으로 보이려나 싶네요 혹여나 강의 중에 설명 주셨는데, 재질문 드리는 거라면 정말 죄송합니다.항상 좋은 강의 감사합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
std::future에서 사용되는 쓰레드의 개수
std::future에서 비동기적으로 함수를 처리하기 위해서 사용하는 쓰레드는 미리 생성된 쓰레드를 통해서 처리하는 건가요?만약, 미리 생성된 쓰레드를 통해서 처리한다면 미리 생성된 쓰레드의 개수는 알 수 있나요? 그리고 해당 쓰레드의 개수도 수정할 수 있을까요?답변 부탁드립니다. 감사합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
싱글스레드가 안전한 이유?
싱글 스레드가 멀티스레드 이슈로부터 안전한게 다른 스레드의 개입이 없어서라고 알고있습니다.멀티코어 다중 스레드 PC에서 싱글스레드 프로그램을 동작시킨다 가정합니다.싱글스레드 환경에서 메인스레드 한개만 동작할것이고 스레드 아이디가 123이라 치고싱글 스레드 환경에서 변수 a가 있다치고 무한루프로 증가 시킨다고 칠때 컨텍스트 스위칭이 일어나도 a라는 변수는 무조건 스레드 아이디 123이고 같은 코어에 있는 스레드가 동작시키는 건가요??컨텍스트 스위칭 과정에서 운영체제가 스레드를 맘대로 할당해 주는 것으로 알고 있는데 다른 코어에 잇는 스레드를 할당해 줄수도 있지 않나해서요.그럼 다른 코어에 있는 캐시 등에 접근 가능하여 가시성, 코드 재배치 문제가 잇지 않을까합니다
-
해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
PacketSession 강의에서 LOCK 크래시 관련
좋은 강의 감사합니다! 해당 강의에서, 다수의 클라이언트 세션이 접속된 상태에서 클라이언트 연결을 끊었을 때, 크래시가 나는 부분을 강의를 멈춰놓고 파악을 해 보았는데요, 이 경우 디스커넥트 이벤트가 발생하면서 OnDisconnected()가 호출되고, GameSessionManager()의 Remove() 함수가 다른 스레드에서 호출될 수 있다는 사실까지는 파악해서, _sessions.erase(session);이 코드가 문제가 된 것 까지는 파악했습니다.그런데 sessions.erase(session); 코드와, 아래의 session에서 루프를 돌만서 Send를 시키는 부분은 같은 WRITE_LOCK으로 보호가 되고 있는 상태라, 우선 루프를 끝까지 돌아 각 세션에 대한 send가 끝난 후 스코프를 빠져나가 WRITE_LOCK이 풀린 후 _session.erase()가 일어날 것이라고 생각해서 이 부분은 문제가 아닐 거라 생각했고, 결국 문제를 찾지 못하고 강의를 들었는데요, 강의에서는 이 부분에 대해서 따로 설명이 없는 것 같아, 왜 저 부분의 WRITE_LOCK 이 문제가 되었고, 루프를 도는 도중에 erase가 일어난 것인지 궁금합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
AcceptEx()에 recvBuffer 지정시
AcceptEx 문서를 보니, AcceptEx에 버퍼를 지정 시, 해당 버퍼에 기본적으로(sizeof (sockaddr_in) + 16) * 2 만큼의 데이터가 담겨 오는것으로 보입니다. 문서에는 "서버의 로컬 주소 및 클라이언트의 원격 주소" 라고 되어있네요. ProcessAccept에서 따로 해당 크기만큼 버퍼의 OnWrite()를 해주지 않고 있는데,해당 데이터는 현재 Listener에서 따로 처리하지 않으니, 버퍼에는 기록이 되었을지언정사용하는 데이터가 아니니 WritePos를 갱신시켜주지 않는 것으로 이해가 되었습니다. 그런데 만약 FreeSize()가 (sizeof(sockaddr_in) + 16) * 2 보다 작게 남아 있었다면버퍼가 초과되어 정의되지 않은 동작이 일어나거나, 혹은 AcceptEx()가 실패하거나 하는 이상이 있을 것으로 보이는데,본문과 같이 별다른 처리를 하지 않아도 문제가 없는 것인지 궁금합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
JobTimer 강의 관련 질문을 드립니다.
안녕하세요. 선생님.항상 좋은 강의를 위해 고생많으십니다.다름이 아니라 JobTimer강의를 보던 도중 Atomic과 lock을 함께 사용하여서 TimerItem을 꺼내는 코드를 작성해주셨는데요.아래와 같이 2가지 사항이 궁금합니다.1. lock과 Atomic을 함께 쓰시는 경우는 특정 컨테이너에서 작업을 다 꺼내고 추가적인 작업을 할 경우, lock 점유 시간을 줄이고 싶으실 때에 Atomic을 함께 사용하시는 것이라 보면 될까요?2. 이것이 맞다면, 보통 Atomic을 함께 써야하는 'lock 점유 시간이 긴' 작업은 어떤 기준으로 판단하시는 지가 궁금합니다.시간내주시고 확인해주셔서 감사합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
bufferwriter << 오버로딩 궁금한 점이 있습니다.
const T& 버전과 T&& 버전으로 오버로딩 되어 있는데T&&가 보편참조라서 const T& 버전이 사용이 안되는건 아닌지 궁금합니다. 그리고 T&& 버전에서 std::move를 왜 사용하는건지 궁금합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Spinlock과 랜덤 메타의 차이
안녕하세요, Rookiss님수업을 듣다가 궁금한 점이 있어서 질문 드립니다. Spinlock의 경우 프로세스 및 쓰레드가 공유 자원에 접근하기 위해 지속적으로 대기하기 때문에 이로 인한 CPU 성능 부하가 발생한다고 저는 이해하였습니다. 따라서 위와 같은 Spinlock의 단점을 보완하기 위해 랜덤 메타에서는 sleep 혹은 yield라는 함수를 사용하였는데, 이는 프로세스 및 쓰레드(?)를 running 상태에서 asleep 상태로 변경하는 것으로 저는 이해하였습니다. 그러면 이 과정에서 자연스럽게 context switching에 의한 오버헤드가 지속적으로 발생하게 되며, 이로 인한 오버헤드가 Spinlock에 의한 오버헤드보다 더 큰 경우도 발생하지 않을까요? 예를 들면 this_thread::sleep_for(std::chrono::milliseconds(100))이라는 함수를 while문 내부에 작성한다면, 프로세스 및 쓰레드는 100ms를 간격으로 지속적으로 running 상태와 asleep 상태를 순회할 것입니다. 이 과정에서 context switching이 발생하게 되고, 이로 인한 오버헤드가 Spinlock에서 while문을 지속적으로 순회하는 오버헤드에 비해 더 큰 경우도 발생하지 않을까요? 감사합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
DBBind에 대한 질문입니다.
DBBind 클래스에 _paramIndex와 _columnIndex 필드가 있는데 어떤 역할을 하고 있는지 모르겠습니다.코드를 따라가 보면 ::SQLBindParameter 함수의 마지막 인자로 들어가게 되는데, 결국 모든 경우에 0을 전달하게 됩니다.그렇다면 굳이 이럴 필요 없이 0을 전달하면 되는 것 아닌가요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
패킷 사이즈에 대한 질문 드립니다.
강사님 네트워크 wsabuf.buf 는 char포인터 형으로 되어 있는데 패킷을 보내게 될때 패킷에 사이즈를 넣어주도록 설계가 되어있는데 char형이라면 127 크기 까지의 패킷만 보낼 수 있는 건가요?
-
해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
ABA problem가 잘 이해가 안돼요
여기에서, 5000번지->6000번지->7000번지 이렇게 각각 연결되어있는데,interlock을 잡기 이전에 2번의 pop과 1번의 push가 일어났고, 그때 5000번지에 다시 새 데이터가 할당돼서 push된 상황이므로5000번지 -> 7000번지인 상황이 만들어졌다고 하셨는데,애초에 이 상황까지 만들어졌다면 push에서 atomic하게 5000번지가 header에 삽입되는 동시에 5000번지의 next도 7000번지로 바꿔줄텐데그때 expected = header->next;의 주소가 아직 5000번이라면 5000번지가 pop이되고 5000번지의 next가 header가 되는데, 이미 5000번지의 next는 7000번으로 Push부분에서 이미 변경되었으니 정상적으로 header는 7000번지의 주소를 가리키는게 맞는거 아닌가요?어떤 부분에서 생각이 틀린건지 잘 이해가 안됩니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
OUT 키워드
Reader-Writer Lock에서Read Lock과 Write Lock을 할 때 compare_exchange에서 OUT 키워드를 사용하는데 이 키워드를 왜 쓰는지 어떨 때 쓰는지 궁금합니다!!if (_lockFlag.compare_exchange_strong(OUT expected, expected + 1))
-
해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
동일한 쓰레드의 소유권 정책에 대해 궁금합니다.
안녕하세요!동일한 쓰레드가 write_lock을 잡고 있을 때는 read_lock을 잡을 수 있지만 read_lock을 잡고 있을 때에는 write_lock을 잡을 수 없다는 것 까지는 이해가 됐습니다.그래서 ReadLock() 메소드에서 같은 쓰레드가 write_lock을 잡고있는지 체크를 해서 잡고있다면 단순하게 read flag를 1 증가해서 통과해주고 있죠.근데 그렇다면 WriteLock() 메소드에서는 동일한 쓰레드가 read flag로 0을 갖고있는지 확인해야 하는 것 아닌가요? R -> W가 허용되지 않는다면, write_lock을 시도 할 때에 동일 쓰레드의 read flag가 0인지 체크하는 코드가 없어도 되는 이유가 뭔지 궁금합니다!
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
iocp server에서 dedicated server
안녕하세요 ! 어렵지만 열심히 반복해서 서버 강의를 듣고있는 학생입니다.다름이 아니라 iocp 서버로 Lobby를 제작하고 dedicated server로 InGame을 제작해서 2개의 서버를 함께 돌리려고 합니다.iocp server로 Lobby Level을 구성하고 3명이 한팀을 이뤄 MatchMaking을 통해 dedicated server로 만들어진 InGame Level로 넘길 생각입니다!iocp server와 dedicated server를 연결해두고, 클라이언트들을 옮기는 방식을 쓰려고 구상을 했는데, 제가 만든 iocp server와 dedicated server를 어떻게 연결할지 감이 안와서 질문드립니다.혹시 이 방법이 불가능한지에 대해서도 여쭙고싶습니다. 감사합니다
-
해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
공부방법에대한 질문입니다
강의를 한 번 정주행 하였는데 코드는 이해가 어느정도 가기는 하지만 이를 어떻게 활용해야 할지 갈피가 잡히지 않네요 ㅠㅠ강의를 반복해서 들어보는게 좋을까요? 아니면 혼자 프로젝트를 진행해 보는게 좋을까요??
-
해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
compare_exchange_strong 의사 코드에 대해 질문이 있습니다!
expected가 레퍼런스로 들어가서 expected의 값을 while 안에서 계속 false로 초기화해주는 것에 대해 좀 의구심이 듭니다. 그냥 expected 자리에 레퍼런스 대신 boolean 리터럴 값으로 false를 넘겨도 문제가 없을 것 같은데, 왜 굳이 레퍼런스를 넘기도록 강제하고 있는 것일까요? if (mbLocked == expected) { expected = mbLocked; _locked = desired; return true; } else { expected = mbLocked; return false; }이 의사 코드에 보면그냥 return true, return false만 해줘도 될 것 같은데 굳이 expected를 초기화 해주는 이유가 궁금합니다.제대로 알려면 어셈블리 레벨에서 도는 코드를 봐야 하는 걸까요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
메모리 동적할당 질문 드립니다.
안녕하세요 강사님 동적 할당으로 메모리를 할당해서 패킷을 보낼려고 하는데왜 (int dir, bool wDown) 값을 추가해서 메모리를 동적할당 하게 되면 메모리 엑세스 위반 에러가 나오게 되는건가요?왜 이런 에러가 뜨는건지 감을 못잡겠어서 질문 드립니다...
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
공부방법에 대해서 질문드립니다
공부방법을 어떻게 하면 좋을까요?강의를 듣고 스스로 코드를 구현해보는 방식으로 하면 될까요??
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
queue의 데이터 이외의 공간?
MemoryPool에서 queue나 vector을 사용하면 데이터 뿐만 아니라, 데이터를 담아두기 위한 공간이 별도로 할당된다고 하셨습니다. 이 별도의 공간이 무엇인지 잘 모르겠습니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
sleep_for과 yield 차이 질문드립니다.
안녕하세요! 멀테스레딩 강의(Lock 구현 부분) 수강 중에 제가 제대로 이해가 안 가는 부분이 있어서 질문드립니다.구체적으로 강의 코드에서 sleep_for와 yield의 내부적 동작?을 저는yield(): lock이 잠겨있는 경우, system time slice에 상관없이 바로 context switching이 발생해, 해당 스레드가 다시 운영체제 스케줄링 큐에 들어가 운영체제가 다시 실행시켜 줄 때까지 대기sleep_for(n): lock이 잠겨있는 경우, yield와 마찬가지로 컨텍스트 스위칭이 바로 발생하는데, n시간동안 해당 스레드가 sleep thread 큐에 저장되어 있다가, 그 다음에 스케줄링큐로 들어가서 이후에 다시 실행될때까지 대기이해했는데, 이게 제대로 이해한게 맞을까요?특히 sleep_for의 동작이 이해가 잘 안가는데, 스택오버플로우에서는 https://stackoverflow.com/questions/17325888/c11-thread-waiting-behaviour-stdthis-threadyield-vs-stdthis-threadsleep_for(n)의 경우 최소 n시간 이상을 block한다는데, 해당 스레드가 블록되었다는 말이 컨텍스트 스위칭이 되어있다는걸까요? 또 sleep thread queue는 운영체제에서 관리하는 개념일까요? (제대로 이해를 못해서 질문이 두서 없는 점 죄송합니다....)