인프런 커뮤니티 질문&답변

fhan님의 프로필 이미지
fhan

작성한 질문수

[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버

Session #2

send 에 lock걸어 주는 것에 질문있습니다.

작성

·

547

0

wsasend가 멀티쓰레드환경을 보장하지 않아 lock을 걸어준다고 하셨는데 어떤부분을 보장하지 않는 건가요?

버퍼문제라면 혹시 이번 수업의 코드는 임시로 event마다 독립적인 버퍼를 가지게 했으니  lock을 안걸어주어도 되나요?

 wsarecv 는 멀티쓰레드환경에서 문제가 발생하지 않나요?

답변 1

0

Rookiss님의 프로필 이미지
Rookiss
지식공유자

앞으로 API 관한 부분은 늘 궁금함이 생기실텐데
항상 정답은 MSDN이나 구글에 있다고 보셔야 합니다.

https://social.msdn.microsoft.com/Forums/en-US/1f85557c-15f6-42b3-a8f7-1630b4099bb6/wsasend-from-multiple-thread-safe?forum=vcgeneral

fhan님의 프로필 이미지
fhan
질문자

https://stackoverflow.com/questions/28770789/is-calling-wsasend-and-wsarecv-from-two-threads-safe-when-using-iocp

여기서 보면 wsarecv도 멀티쓰레드환경에서 사용하면 위험하다고 하는데 수업코드에서는 recv할때는 lock이 안 결려있어서 질문드립니다

Rookiss님의 프로필 이미지
Rookiss
지식공유자

recv에서 락을 안 건 이유는, 애당초 RegisterRecv를 딱 1개만 걸어줬기 때문입니다.
따라서 2 쓰레드가 동시에 WSARECV를 호출할 경우의 수가 나오지 않습니다.
반면 Send는 밖에서 신나게 원하는 타이밍에 호출할 수 있어서 상황이 다릅니다.

fhan님의 프로필 이미지
fhan
질문자

ClientServiceRef service = MakeShared<ClientService>(

NetAddress(L"127.0.0.1", 7777),

MakeShared<IocpCore>(),

MakeShared<ServerSession>, // TODO : SessionManager 등

1);

이부분에서  마지막인자를 1로 설정했기 때문이라는 말씀이신거죠? 

이렇게 하면 실질적으로 한명의 유저만이 서버에 접속하게 되는 것이어서 lock을 안 걸어준 것이라고 이해하면 될까요?

Rookiss님의 프로필 이미지
Rookiss
지식공유자

아뇨 그 부분은 아닙니다. 동접이 5천명이라 하더라도,
한 유저에 대해서는 Recv를 한 번에 1번만 호출해주게 될 것이라는게 핵심입니다.
현재 구조에서 RegisterRecv -> ProcessRecv -> RegisterRecv -> ProcessRecv
이렇게 계속 왔다 갔다 하면서 패킷 수신이 이루어지고 있는데요.
이 부분은 제가 강의에서 낚시대에 비유를 많이 하곤 합니다.
낚시대가 유저마다 딱 1개만 있고, 이 낚시대를 바다에 던져서 물고기를 잡고,
물고기를 끌어올리고 다시 낚시대를 바다에 던지는 행동을 반복하겠죠.

RegisterRecv가 멀티쓰레드 환경에서 돌아간다고는 하나,
어차피 동일한 세션에 대해 RegisterRecv가 동시에 두 번 호출될 수 없습니다.
따라서 굳이 Recv할 때 락을 걸어줄 필요가 없는 것입니다.

fhan님의 프로필 이미지
fhan
질문자

음...... 그렇다면 RegisterSend는 동일한 세션에 대해 동시에 두 번 호출되는 경우가 있나요?

Rookiss님의 프로필 이미지
Rookiss
지식공유자

Send는 외부에서 원할 때 호출할 수 있으니, 
별도 안전 처리를 하지 않으면 여러번 호출될 수 있습니다.
따라서 락을 걸던, 이전 애가 보낼 동안에는
데이터를 보내지 않는 등 무엇이든 좋으니 보호를 해줄 필요가 있습니다.

fhan님의 프로필 이미지
fhan
질문자

이해됬습니다... 감사합니다^^

fhan님의 프로필 이미지
fhan

작성한 질문수

질문하기