inflearn logo
강의

Course

Instructor

[C# and Unity MMORPG Game Development Series] Part 7: MMO Content Implementation (Basics of Unity + C# Server Integration)

Skill #1

Room내 BroardCast시 질문입니다

366

namopp

11 asked

0

룸에서 BoardCast로 패킷을 보낼때
Send시에 lock을 걸어야할 이유가 있을까요?

lock(_lock){

   임시 list에 players의 player를 넣는다

}

foeach (player in  임시 list ) {

    player.Send 호출

}

로 했을때도 문제가 없는것 같은데 
제가 발견하지 못한 문제가 있다면 어떤 문제가 있는지 궁금합니다

C# unity

Answer 4

0

Rookiss


Send 내부에서 int a = 3; 같은 변수를 만들어서 사용하면
지역 변수이고 스택 영역에 들어가기 때문에 쓰레드 경합에 안전하지만,
전역 메모리나, Heap 메모리 쪽은 항상 위험(?)이 도사리고 있습니다.

동일한 Session을 다수의 쓰레드에서 참조한다면,
현재 _sendQueue, _pendingList 등 _가 붙은 시리즈들은
Thread-Safe하지 않습니다.
따라서 현재 상태로도 lock이 반드시 필요합니다.

0

namopp

음.. 답변주신걸 다시 한번 쭉 보니
제가 질문 자체를 모호하게 드렸던것 같네요 ㅠ 죄송합니다
그리고 제가 궁금했던 내용에 대한 답변은 처음에 주셨는데 혼란만 드렸네요 ㅠ


다른분들도 혼란이 될 수 있을까봐 코드로 첨부합니다

1.HandlerMove 함수 안에 
lock 처리를 하여 플레이어 정보의 정보등을 수정 또는 가져와서 패킷을 만든뒤

2. BroadCast 함수를 호출하고
다시 내부적으로 lock 을 하면서 foreach로 순회하며 send를 하게 되는데요

이부분을 아래 처럼 변경을 해도 이상없는지에 대한 의견이였고

답변주신내용은: 

Send 내부적으로도 lock 처리가 되고 있기 때문에,
위에서 수정하신 대로 해도 무방합니다.
복사 비용이 약간 추가되지만,
반대로 쓰레드 경합 측면에서는 이점이 생기겠죠


이것으로 정리하겠습니다. 감사합니다

0

Rookiss

Send는 꼭 Broadcasting할 때만 호출하는게 아니고
언제 어디서든 호출할 수 있습니다.
가령 어떤 유저한테 귓말을 하는 상황이라면,
해당 유저한테 메시지 패킷을 만들어서 Send를 날려야 하는데,
대부분 SessionManager에서 세션을 찾아서 바로 Send를 꽂아주게 됩니다.
따라서 Send는 다수의 쓰레드에서 진행될 수 있기 때문에
내부적으로 어떠한 형식으로든 동기화 처리를 해줄 필요가 있습니다.
그리고 실질적으로 네트워크 라이브러리 송수신 함수들(RecvAsync, SendAsync 등)이
Thread-Safe하지 않게 설계 되었기 때문이기도 합니다.

0

namopp

친절한 답변에 다시 한번 감사드립니다 !

벌써부터 c++ 강의가 기다려지네요 ㅎ

쓸모없는 질문같지만 양해를 부탁드리며 이어서 추가 질문 드리겠습니다!
(이해가 안가는 부분들이라 확실하게 짚고 넘어가고 싶네요 ㅠ 죄송합니다)

질문 : 
귓말 처럼 바로 Send에 꽂아주기 때문에
Send가 다수의 쓰레드에서 진행이 될 수 있다고 말씀하셨는데요

현재  Send함수내부에서 사용되는 변수들이
모두 지역변수 형태로 생성되고 쓰임되는것 같아 Thread-Safe하다고 판단이 되는데
추후 Send 함수 내부에 전역적으로 접근이 될 변수들이 생겨나게 되는건가요?


0

namopp

감사합니다
추가적인 질문으로  있습니다.

위에 제가 질문드린대로 복사 비용을 소비하고 진행하려고 할때
Send 내부적으로 lock 필요한 이유가 잘 이해가 안갑니다

내부적으론 경합이 일어날 이유가 없어보이거든요(sendQueue에 들어갈시에 lock처리 중..)

이부분에 대해서도 다른 이유가 있을까요?

0

Rookiss

Send 내부적으로도 lock 처리가 되고 있기 때문에,
위에서 수정하신 대로 해도 무방합니다.
복사 비용이 약간 추가되지만,
반대로 쓰레드 경합 측면에서는 이점이 생기겠죠.

다만 Broadcast는 하나의 예시입니다.
이번에는 운 좋게 foreach 내부에서 하는 것이
Send 하나 뿐이라 Thread-Safe 해서 별 문제 없었지만
실제로 전투 컨텐츠를 작업하다 보면
그렇게 할 수 없을 때가 많습니다.
(ex. 와우의 블리자드 스킬처럼 광범위한 데미지를 모두에게 준다거나..)

MessagePack

0

85

1

본인 플레이어 이동 관련 질문

0

49

1

Part7 Part9 질문이 있습니다.

0

72

1

.

0

116

1

.

0

106

2

게임 로직 루프에서 게임 틱 누락으로 인한 높은 CPU 사용 문제

0

92

1

타일 팔레트 깔았는데도 안돼요

0

116

2

2D로 그냥 만들어도 되나요?

0

81

2

지난 강의와 이어지는게 맞을까요?

0

80

2

순환참조 문제로 인해 발생하는 문제는 없을까요?

0

162

2

유니티 클라와 C++서버연동

0

277

2

멀티플레이 테스트 환경 관련 질문입니다

0

207

3

강의 후반부에 순서 동기화를 위해 잡큐를 사용 안 한 부분 질문입니다!

0

150

2

코드 관련한 몇 가지 질문입니다!

0

153

2

3d 프로젝트 이동 동기화 관련

0

321

4

파트 7 스트레스 테스트 질문 드립니다.

1

189

2

맵 이동 방식

0

133

0

맵 이동 관련해서 질문드립니다.

0

91

1

안녕하세요 도저히 알 수 없는 오류가 나와서 질문드려요,,

0

201

2

안녕하세요. 일전에 질문 드린 포폴 준비 관련 질문의 추가 질문입니다!

0

160

1

[팁] 2024년 기준 버전 이슈?

0

455

1

SendBuffer.cs 삭제 후 대체 되는 부분의 장단점?

1

203

1

지금 강의의 유니티 클라를 IOCP 서버와 연동하는 것

0

336

2

PushAfter 사용 질문

0

192

1