• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    해결됨

TickRoom 함수

20.10.04 20:57 작성 조회수 293

1

안녕하세요 

TickRoom 함수에 람다 함수를 room.Update(); 로 넣어주셨는데 room.Push(room.Update); 를 넣어야 lock이 실행되는게 아닌지 궁금합니다~!

static void TickRoom(GameRoom room, int tick = 100)

        {

var timer = new System.Timers.Timer();

timer.Interval = tick;

timer.Elapsed += ((s, e) => { room.Update(); });

timer.AutoReset = true;

timer.Enabled = true;

_timers.Add(timer);

        }

답변 8

·

답변을 작성해보세요.

3

제대로 이해하신 것이 맞습니다.
그렇다면 싱글쓰레드로 게임 로직으로 실행하니, 
기껏 멀티쓰레드를 배우고 활용 못하는 것 아닌가? 싶기는 하지만
이 방법을 완전히 익히고 이해해야 더 어려운 기법을 사용할 수 있습니다.

서버 구조와 관련된 내용은 Part9에서 언급을 하는데, 미리 스포일러를 드리자면
블소, 뮤 같이 심리스 구조가 아니라면 (즉 한 구역에서 다른 구역으로 넘어갈 때 로딩이 있으면)
구역 자체에 하나의 JobSerializer를 두고
단일 쓰레드로 실행하는게 일반적입니다. (현재 코드로 치면 GameRoom)

반면 와우, 리니지 같이 전체 월드가 심리스 구조라서
모든 구역에 서로 연결이 되어 있을 경우
구역 단위로 쪼개서 구역마다 하나의 JobSerializer를 두거나,
모든 게임 오브젝트 (몬스터, 플레이어, 투사체 등등)마다 JobSerializer를 두는 2가지 방식 중 선택을 하게 됩니다.
참고로 2방식 모두 말은 쉽지만
컨텐츠 구현이 매우 어려워지기 때문에
본 시리즈에서 다루지는 않고, 추후에 만들 C++ 버전에서는 살펴볼 계획입니다.

1

Job 기반 방식 (다른 이름:Task, Message)으로 수정을 하셨다면,
1, 2, 3 모두 아닙니다 !

lock은 이제 JobSerializer 쪽의 Queue에 Push/Pop할 때만 걸리게 됩니다.
주방장과 서빙 직원이 주문서를 주고 받을 때만 lock이 걸린다고 보시면 됩니다.
즉, 최초로 일감을 밀어넣는 Push할 때만 걸리고,
반대로 일감을 추출해서 실행하는 Flush 부분에서도 걸리지만,
각각 함수 (Update, OnDead, LeaveGame 등) 실행(요리 과정)이랑은 무관합니다.

1

1) 명시적으로 우리가 쓰레드나 Task를 사용하는 경우
2) 특정 비동기 함수 or 특정 클래스 기능에서 간접적으로 사용하는 경우
로 구분할 수 있는데 C#의 System.Timers이나 네트워크 관련 기능들은 2번에 해당합니다.

참고로 C++의 경우 명시적으로 쓰레드를 만들어서 쓰는 경우가 대부분입니다.

0

감사합니다!

0

답변 감사합니다~!

그러면 혹시 제가 생각한 다음 흐름이 맞는지 궁금합니다.

1) System.timers에서 하나의 쓰레드에 1번 GameRoom에 대한 일감을 모두 할당함

2) 결국 하나의 쓰레드에서 1번 GameRoom의 일감을 처리하게되는데, 만약 외부 클래스(e.g. ClientSession)에서 일감을 Push로 넣어줬다면 이런것까지 모두 (아까것과 같은) 하나의 쓰레드에서 일감을 처리함

만약 이게 맞다면 하나의 게임룸에 대한 일감을 하나의 쓰레드에서 처리하게 되면서 만약 일감이 몰릴경우 버벅이거나 하는 성능저하가 발생할 가능성은 없는지 궁금합니다~!

0

안녕하세요

계속 비슷한 질문을 드려서 죄송합니다..ㅜ

OnDead가 호출되었을때, 어느타이밍에 lock이 걸리는지 궁금합니다.

코드 흐름을 따라갔을 때는 다음과 같았습니다.

Programs의 TickRoom에서 room.Update() 호출

1) monster.Update() 실행

2) monster 사망으로 인해 OnDead() 호출 

3) room.LeaveGame(Id); 호출

이런 흐름에서  lock을 어느타이밍에 걸고있는건지 궁금합니다..

0

답변 감사합니다.

 문득 c# 게임 서버에서 멀티 쓰레드 환경이 언제 가동되는지 궁금합니다.

1) Invoke 함수를 사용할 때

2) System.timers 함수에 함수를 넘겨줄 때

3) 모든 환경에서 자동으로?

0

저 코드를 만들 때 기준으로는  Push에서 Flush하는 부분을 제거했으니,
실질적으로 실행 담당은 혼자라서 상관없습니다.
(누군가는 Flush을 해줘야 하는데 그걸 Update에 넣어준 셈)

만약 이전처럼 Push한 애가 Flush도 하게 만들었다면 다른 얘기가 되겠죠.