작성
·
309
답변 4
0
Send 내부에서 int a = 3; 같은 변수를 만들어서 사용하면
지역 변수이고 스택 영역에 들어가기 때문에 쓰레드 경합에 안전하지만,
전역 메모리나, Heap 메모리 쪽은 항상 위험(?)이 도사리고 있습니다.
동일한 Session을 다수의 쓰레드에서 참조한다면,
현재 _sendQueue, _pendingList 등 _가 붙은 시리즈들은
Thread-Safe하지 않습니다.
따라서 현재 상태로도 lock이 반드시 필요합니다.
0
Send는 꼭 Broadcasting할 때만 호출하는게 아니고
언제 어디서든 호출할 수 있습니다.
가령 어떤 유저한테 귓말을 하는 상황이라면,
해당 유저한테 메시지 패킷을 만들어서 Send를 날려야 하는데,
대부분 SessionManager에서 세션을 찾아서 바로 Send를 꽂아주게 됩니다.
따라서 Send는 다수의 쓰레드에서 진행될 수 있기 때문에
내부적으로 어떠한 형식으로든 동기화 처리를 해줄 필요가 있습니다.
그리고 실질적으로 네트워크 라이브러리 송수신 함수들(RecvAsync, SendAsync 등)이
Thread-Safe하지 않게 설계 되었기 때문이기도 합니다.
친절한 답변에 다시 한번 감사드립니다 !
벌써부터 c++ 강의가 기다려지네요 ㅎ
쓸모없는 질문같지만 양해를 부탁드리며 이어서 추가 질문 드리겠습니다!
(이해가 안가는 부분들이라 확실하게 짚고 넘어가고 싶네요 ㅠ 죄송합니다)
질문 :
귓말 처럼 바로 Send에 꽂아주기 때문에
Send가 다수의 쓰레드에서 진행이 될 수 있다고 말씀하셨는데요
현재 Send함수내부에서 사용되는 변수들이
모두 지역변수 형태로 생성되고 쓰임되는것 같아 Thread-Safe하다고 판단이 되는데
추후 Send 함수 내부에 전역적으로 접근이 될 변수들이 생겨나게 되는건가요?
0
감사합니다
추가적인 질문으로 있습니다.
위에 제가 질문드린대로 복사 비용을 소비하고 진행하려고 할때
Send 내부적으로 lock 필요한 이유가 잘 이해가 안갑니다
내부적으론 경합이 일어날 이유가 없어보이거든요(sendQueue에 들어갈시에 lock처리 중..)
이부분에 대해서도 다른 이유가 있을까요?
0
Send 내부적으로도 lock 처리가 되고 있기 때문에,
위에서 수정하신 대로 해도 무방합니다.
복사 비용이 약간 추가되지만,
반대로 쓰레드 경합 측면에서는 이점이 생기겠죠.
다만 Broadcast는 하나의 예시입니다.
이번에는 운 좋게 foreach 내부에서 하는 것이
Send 하나 뿐이라 Thread-Safe 해서 별 문제 없었지만
실제로 전투 컨텐츠를 작업하다 보면
그렇게 할 수 없을 때가 많습니다.
(ex. 와우의 블리자드 스킬처럼 광범위한 데미지를 모두에게 준다거나..)
음.. 답변주신걸 다시 한번 쭉 보니
제가 질문 자체를 모호하게 드렸던것 같네요 ㅠ 죄송합니다
그리고 제가 궁금했던 내용에 대한 답변은 처음에 주셨는데 혼란만 드렸네요 ㅠ
다른분들도 혼란이 될 수 있을까봐 코드로 첨부합니다
1.HandlerMove 함수 안에
lock 처리를 하여 플레이어 정보의 정보등을 수정 또는 가져와서 패킷을 만든뒤
2. BroadCast 함수를 호출하고
다시 내부적으로 lock 을 하면서 foreach로 순회하며 send를 하게 되는데요
이부분을 아래 처럼 변경을 해도 이상없는지에 대한 의견이였고
답변주신내용은:
Send 내부적으로도 lock 처리가 되고 있기 때문에,
위에서 수정하신 대로 해도 무방합니다.
복사 비용이 약간 추가되지만,
반대로 쓰레드 경합 측면에서는 이점이 생기겠죠
이것으로 정리하겠습니다. 감사합니다