월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Send하는부분 전체적인 로직 질문입니다.
Send함수 : _pending이 true일 때 -> 지금 RegisterSend를 하고 있으니 등록하지 않고 대기열(큐) 에 넣어준다. _pending이 false일 때 -> 지금 RegisterSend를 하고있지 않으니 RegisterSend를 실행한다. 동시에 Send를 실행할 수 있으니 lock을 걸어줘야 한다. RegisterSend함수: _pending을 true로 바꿔서 실행중이라는 것을 표시, 큐에서 버퍼 하나를 꺼내서 SendAsync를 비동기로 실행, 완료되면 OnSendCompleted를 호출한다. Send에서 호출하는 경우와 OnSendCompleted 에서 호출하는 두 가지 경우가 있지만, Send에서는 _pending이 false일때 호출, OnSendCompleted에서는 _pending이 true일 때 호출하기 때문에 lock을 걸어주지 않아도 된다. OnSendCompleted 함수: RegisterSend을 하는 동안 큐에 쌓인 버퍼를 전부 처리하고 _pending을 false로 바꿔서 일을 끝냈다고 표시한다. 직접 호출과 콜백 두 가지 경로로 올 수 있기 때문에 lock을 걸어줘야한다. 대충 이렇게 이해했는데 이해한게 맞을까요..?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
OnAcceptCompleted 코드에서 질문이 있습니다.
1. Action.Invoke(), Func.Invoke() Invoke() 함수가 많이 등장하는데 MSDN을 살펴봐도 딱히 나오는 내용이 없더군요. 느낌상 <T> 제네릭 객체를 반환하는 것 같은데 어떤 기능을 하는지 잘 모르겠습니다. 2. 다형성에 관한 질문 OnAccpetCompleted에서 if (args.SocketError == SocketError.Success) { Session session = _sessionFactory.Invoke(); session.Start(args.AcceptSocket); session.OnConnected(args.AcceptSocket.RemoteEndPoint); } 라는 코드가 있습니다. 여기서 _sessionFactory에 ( ) => { return new GameSession( ) } 람다함수가 들어있습니다. _sessionFactory는 Func<Session> 이므로 람다함수가 반환한 GameSession이 Session 으로 형변환이 될 것 같습니다. 그리고 _sessionFactory.Invoke( )를 하면서 Session 객체를 반환할 것 같습니다. <-- 1번 질문 그런데 여기서 반환된 Session 객체가 OnConnected라는 메소드를 가질 수 있다는게 잘 이해가 안갑니다. _sessionFactory에 람다함수를 연결하는 과정에서 GameSesison이 Session을 형변환을 했으면, GameSession에 Override된 OnConnected를 쓸 수 없는거 아닌가요? 어떤 부분이 틀렸는지 알려주시면 감사하겠습니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
이렇게 이해하면 될까요?
안녕하세요. 제가 이해한 대로 적어봤는데 한번 읽어보시고 잘 이해했는지 확인해주셨으면 감사하겠습니다 메인에서 쓰레드 1, 2가 동시에 실행이 되서 WaitAll(t1, t2);에 의해 쓰레드 두 개가 끝날때까지 WaitAll에서 기다리게 된다. 쓰레드1, 2가 동시에 Test()를 호출하게 되면, SessionManager의 _lock과 UserManager의 _lock이 동시에 락이 되어 버린다. 이 상태에서 각자 TestSession(), TestUser()를 호출하게 되는데, 이 시점에서 SessionManager와 UserManager의 _lock은 이미 락이 된 상태이기 때문에 _lock이 풀릴때까지, 즉 Test() 함수에서 lock{} 블록이 끝날때까지 대기한다. 하지만 서로 _lock 클래스 멤버변수가 lock되어 있는 상태이기 때문에, 서로 lock {}문을 빠져나올 때까지 무한히 기다리는 상황이 벌어지게 된다. 만약 t1.Start()만 호출하게 되면 SessionManager의 Test()가 호출하게 되고, UserManager의 TestUser()가 호출하게 된다. 이떄는 UserManager의 lock이 락되지 않은 상태이기 때문에 Console.WriteLine이 호출되고 lock을 빠져나오며 SessionManager.Test()도 무사히 나오게 되어 Main을 끝내게 된다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
ContextSwitching 강의를 듣다가 궁금한 것이 생겼습니다.
식당을 예로 들어서 말씀해주셔서 저도 식당에 비유해서 질문 드리자면 여러 직원(쓰레드?)이 있을 때 영혼이 하나의 직원에서 다른 직원 쪽으로 바꿔 빙의할 때 중간에 식당 관리자(커널)이 개입하는 걸로 이해했습니다. 그렇다면 관리자가 빙의시킬 직원을 고를 때 어떤 직원부터 빙의시킬 지 선택하는 기준이 있을 것 같은데 그런 스케쥴링 하는 알고리즘? 같은 것이 커널에 있는 것인가요? 그렇다면 어떤 형태의 알고리즘을 채택하는 것이고 게임 프로그래밍에 있어서 이러한 스케쥴링을 이해하는 것이 좋을지 궁금해서 질문 드립니다! 항상 강의 재밌게 잘 보고 있습니다! 감사합니다!
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
RegisterAccept 함수 내부 질문입니다.
pending이 true일 때 : 클라이언트의 입장을 기다리다가 입장신청을 하면 args.Completed에 등록한 OnAcceptCompleted 이 콜백으로 실행 pending이 false 일 때 : 입장을 받는것과 동시에 입장신청이 와서 콜백함수를 실행할 겨를이 없어서? OnAcceptCompleted를 직접 실행 이렇게 이해했는데 이해한게 맞을까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Send는 Lock이 있고 Recv에는 Lock이 없는 이유가 무엇인가요?
좋은 강의를 만들어주셔서 감사합니다 😀 내용을 정리하다 궁금하게 있어 질문 남깁니다. Send에 Lock이 있는 이유는 멀티 쓰레드 환경에서 동시다발적으로 Send를 호출하는 것을 막기 위해서인데 Recv에는 Lock이 없는 이유가 무엇인가요? Send는 우리가 원할 때 마다 호출해야 하는 반면 Recv는 송신버퍼에 데이터가 들어왔다는 이벤트가 있을때에만 호출하기 때문에 발생하는 차이인가요? 추가로, OnSendCompleted에서 Lock을 걸어야 하는 것도 잘 이해가 가지 않습니다. RegisterSend에서 호출된 경우는 Lock이 필요가 없다는 것이 이해가 갑니다. 그치만 OnSendcompleted가 이벤트 핸들러라서 이벤트 완료됬을 시에만 실행할 수 있는데 그렇다면 여기에 다수의 쓰레드가 아닌, 하나의 쓰레드만 접근할 수 있지 않나요? 이벤트가 완료됬을 시 쓰레드 풀에서 하나의 쓰레드가 개입하여 이벤트핸들러를 처리한다고 들었습니다. 어떤부분이 틀렸는지 알려주시면 감사하겠습니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
AcceptAsync()함수의 pending 상태에 대해서 질문드립니다.
섹션2. 네트워크 프로그래밍 listener 파트에서 AcceptAsync함수에 대해서 궁금한점이 있습니다. AcceptAsync 함수가 처음에 잘 이해가 안가서 디버깅을 해보려고 했는데요. 보통은 pending상태가 true여서 콜백으로 OnAcceptCompleted가 호출되는건 이해가 됬는데, pending 상태가 false인 경우는 어떤 경우인지 궁금합니다. 강의 내용이나 문서를 찾아보고 이해한 바로는 AcceptAsync가 호출되는 경우 이미 Connect요청이 있어서 처리한 경우 콜백으로 호출되지 않고 바로 OnAcceptCompleted를 호출해서 처리한다고 이해했는데요. 그래서 서버쪽에서는 AcceptAsync함수를 호출하기 직전에 중단점을 걸고, 클라이언트쪽에서는 Connect하고 Send까지 한 후에 다시 AcceptAsync를 호출하게 하면 pending=false가 되지 않을까 했는데, 결과는 계속 pending=true인 상태네요. 해당 부분 디버깅을 통해서 확인할 수 있는지 궁금하고, 실무에서 pending이 false로 리턴되는 경우가 자주 있는지 궁금합니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Taks 강제 종료
극단적 예시이긴한데 19:10초에 taks 사용하셨잖아요. while(true) 일때 강제 종료 하려면 어떻게 하나요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
게임서버 파트는 정말로 어렵네요
그나마 강의를 2번씩 들으면서 일단 어찌어찌 알것말것같은 상태를 유지하고 있습니다 혹시 강의와 병행할 수 있는 게임서버와 관련된 교재를 추천해주실 수 있으신가요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
ManualResetEvent 질문있습니다.
1) Auto든 Manual이든 false로 처음에 지정해 놓으면 들어가려는 시도를 할 때 누군가는 문을 열어놓아야하는데 이부분은 따로 구현해주면 되는건가요? Release를 먼저 호출하지는 않을 것 같아서 다른 식으로 문을 열어야 하지 않나 생각이 들어서 질문드립니다. 2) 두 이벤트 방식에서 지정하는 initialState인자는 아토믹한 방식으로 동작하는 건가요? 3) ManualResetEvent 사용 예를 보여주실 때 동작이 이해가 잘 안됩니다. false로 지정해놔서 문이 닫혀있다고 하고, 다른일을 하다가 Set이 호출되어 문이 열리면 WaitOne으로 입장을 시도한다 까지는 이해가 되는데 그러면 AutoResetEvent와 달리 자동으로 문을 닫는게 아니면 다시 문을 닫아주는 함수가 호출이 되어야하는 것 아닌가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
number가 0이 안되는 상황이 이해가 않습니다.
public void Acquire() { while (_locked) // 화장실 문이 비어있을 때 까지 대기를 한다. { } // 들어가서 문을 잠그는 작업 _locked = true; } 이렇게 화장실에 들어가는 과정과 잠그는 과정이 달라서, 그 시간차 동안에 두 쓰레드가 동시에 공유 자원에 접근해서 number에 0이지 나오지 않는다고 설명해주셨습니다. 근데 이 설명이 잘 이해가 가지 않습니다. 위 코드에 화장실에 2명이 들어간다는 게 어떤 의미인가요? 제가 이해한 바로는 _locked이 false가 되어 while문을 빠져나왔을 때 다른 쓰레드도 Acquire함수에 접근하여, 두 쓰레드에서 _locked에 true를 대입하는 것으로 이해했습니다. 근데 이러한 이유 때문에 number++와 number-- 연산에서 에러가 나는 과정이 이해가 되지 않습니다. 결국 for문을 만번이든, 10만번이든 돈 다는 뜻은 number++ 혹은 nunber-- 연산을 했다는 뜻인데 왜 number에 0이 출력되지 않고 이상한 값이 출력되는지 잘 모르겠습니다. number++ 혹은 number-- 연산이 스킵이 되는 과정이 이해가 안갑니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
수업의 코드가 이해가 안되어서 질문드립니다.
Thread1이 TestUser에서 lock이 걸리고 public static void TestUser() { lock(_lock) <-- 요기 { Console.WriteLine("This is TestUser"); } } Thread2가 TestSession에서 lock이 걸리는 걸로 알고 있습니다. public static void TestSession() { lock(_lock) { Console.WriteLine("This is TestSession"); } } 근데 이렇게 해서 데드락이 걸린다는 게 잘 와닿지 않습니다. 수업시간에 2개의 자물쇠를 각각 다른 사람이 잠굴 때 데드락이 발생한다고 하셨는데 위 코드가 그것을 설명하는 내용인가요? TestUser에서 lock이 걸려도 lock안의 코드를 수행하고 나오고, TestSession에서도 lock안의 코드를 수행하고 나오면 되지 않나요? 서로 다른 쓰레드여도 작업하는 공간이 다를텐데 왜 둘다 lock에서 먹통이 되는지 잘 이해가 가지 않습니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Event 방식
AutoResetEvent 방식을 공부하다 궁금한게 생겨서 질문 남깁니다. AutoResetEvent 방식은 강의에서 말씀하신것처럼 운영체제에게 이벤트를 요청하며 CPU 점유를 반환하고 대기하고 있다가, 이벤트가 처리되어 락을 얻을 수 있는 순간이 왔을때, 운영체제가 직접 아까 요청했던 그 쓰레드를 깨워서 실행하도록 하는 방식이라고 이해해도 되나요? 기존의 랜덤메타와 다른건, 이벤트를 등록해두고, 이벤트가 처리되어 본인이 실행될 수 있을때, 다른 스케쥴링을 다소 무시하고 먼저 본인이 새치기하듯 먼저 실행된다고 이해했는데 잘 이해했는지 궁금합니다. 그리고 이러한 방식이 기존의 2번 방식이었던 Sleep, Yield와 같은 랜덤메타 방식보다 좀더 성능적(속도)으로 느리다고 이해했는데 잘 이해했는지 궁금합니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
SpinLock과 Mutex 클래스에 대해
SpinLock은 계속 CPU를 들고 반복한다는걸 알고 있는데, 정확히는 자신에게 주어진 Time slice(시간)을 모두 사용했다면 결국 스핀락 방식도 CPU를 반환하고 나중에 다시 자신의 차례가 됐을때 다시 자신에게 주어진 최대 시간을 모두 사용한뒤 반복하는 과정을 반복한다고 이해하는게 맞나요? 이전에는 정확하게 알지못해서 스핀락 구조일때 정말로 해당 쓰레드는 절대로 CPU(코어)를 돌려주지 않고 영원히 독점하는줄 알았는데 그게 아니라, 운영체제 정책에 따라 자신에게 할당된 최대 시간(time slice) 만큼만 최대로 독점한다는 의미로 이해하는게 맞는지 궁금합니다. 그리고 강의 마지막에서 나온 Mutex 클래스의 동기화 방식은 기존에 학습했던 3가지의 경우(스핀락, 랜덤메타(양보), 이벤트)에서 이벤트와 동일하다고 이해해도 괜찮을까요? 아니면 위의 3가지 경우와 완전히 다른 4번쨰 방식이라고 아는게 좋을까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
멀티코어에서 락을 얻기 위한 경쟁
강의를 듣고 공부하다가 궁금한게 생겨서 질문 남깁니다. 만약 멀티코어 환경에서 1. 서로다른 코어에서 실행중인 서로다른 쓰레드가 2. 동시에 동일하게 실행하고 있던 같은 프로세스 내의 공유자원에 접근하기 위해 락을 얻으려할때, 3. interlocked든 다른 lock이든 정말 미세한 차이가 안날만큼 정확하게 동시에 락을 획득하는 경우는 존재할 수 없나요? 없다면 그 이유가 무엇인지 궁금합니다. (물론, 그럴 확률이 매우 적을수 있다는건 알지만, 완벽하게 이런 경우를 차단할수도 없는게 아닌가 헷갈립니다ㅠ)
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
매치메이킹 질문
멀티 달리기 게임이 있다고 했을때 매치메이킹을 해서 서로 경주하는 게임을 이 서버 강의를 응용해서 만들려고 하는데요 그래서 제가 생각해본결과 서버 포트를 여러개 열어서 매치메이킹된 유저끼리 그 포트를 연결해 게임을 진행시킬려고 하는 방법이 떠올랐어요 포트를 여러개 열어서 사용하는 방법이 안좋은 방법인거 같긴한데, 포트를 여러개 열면 문제되는 문제점이 무엇인가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
lock에 대한 질문이 있습니다.
안녕하세요. lock이 2번 잡혀 있어서 궁금한 점이 있습니다. SendForEach에서 lock이 잡혀있는데, Session에 있는 Send를 받은 곳에서도 lock을 거는 이유가 무엇인가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
lock 질문입니다.
저는 한쪽에만 lock을 걸으면 어떻게 될까? 라는 생각을 가지고 Thread_1에는 lock을 걸고, Thread_2에는 lock을 걸지 않았습니다. Thread_2에서는 lock을 걸지 않아서 lock의 영향을 받지 않기 때문에 Thread_1에서 작업중인 number에 접근할 수 있고, Thread_1에서도 Thread_2에서 작업중인 number에 접근할 수 있어서 난수가 나올 것이라고 예상했습니다. 하지만 몇번을 돌려봐도 결과는 난수가 아닌 0이 나왔습니다. 그리고 질문들을 살펴보다 보니 새로운 object _obj2를 만들어서 Thread_2에 lock을 했을 때는 난수가 나온다는 것을 알았습니다. 서로 다른 object를 통해 lock을 하면 난수가 나온다는 것은 이해했고 이게 제가 예상했던 결과인데, 한쪽에만 lock을 걸었을 경우에는 왜 0이 나오는지 잘 모르겠습니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
MMORPG 동접에 따른 서버 유지비용.
안녕하세요. 게임 강좌와 사실 크게 관련이 없고, 이러한 질문을 드려도 될지 모르겠지만, 파트4~9까지 이곳에서 가르쳐주시는 것의 기반으로 동시접족자 수는 1000명이고, 바람의나라처럼 몬스터 수와 컨텐츠 수 등 비슷하다고 가정했을 때 서버를 만든다면 하루 서버 비용은 대략 얼마정도 예상할 수 있는지 여쭤볼 수 있을까요? 그리고 가정에서 일반 컴퓨터로 서버를 유지할 수는 없는 것인가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
서버 프레임워크
여기서 배운 웹서버와 api서버하고 많이 다른가요 그리고 코딩한 내용이 프레임워크와 같이 된것이 c# 에도 있는지요