inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버

Session #2

listenSocket.AcceptAsync 와 내부에서생성되는 스레드에 대하여..

484

dyl

작성한 질문수 12

0

질문이 https://inflearn.com/questions/238421
이 질문과 유사한 질문이긴 한단계 더 들어가보자면..

만약에
bool pending = _listenSocket.AcceptAsync(args); 이 구문이 실행 될때

동시에 여러 클라이언트에서 접속이 이뤄지면

AcceptAsync 가 두번 실행 되면서
내부적으로 스레드 두개가 돌아가는것 같은데
(ex: AcceptAsync 가 한번 실행되고 완료 되지 않은 상태에서 곧바로 다시 AcceptAsync 가 호출 되는 경우)

이렇게 되면 OnAcceptCompleted 함수가 멀티스레드 로 두개의 Completed 를 두개 실행한 것 처럼 두개의 함수가 동시에 돌아가게 되는것 아닌가요?
(즉 동기화 처리가 필요해지는 상태)

이렇게 되면 순서적으로 처리 되지 않을것은데
왜 순서적으로 처리가 된다는 것인지 잘 이해가 안가는것 같습니다

async 계열들이 내부적으로 쓰레드로 돌아가는 것이라면 다른 것들도 마찬가지 일것 같은데요..

답변 좀 부탁드리겠습니다!

unity network C#

답변 1

0

Rookiss

동시에 여러 클라이언트에서 접속이 이뤄지면
AcceptAsync 가 두번 실행 되면서
내부적으로 스레드 두개가 돌아가는것 같은데

-> 클라 접속이 이뤄지더라도 AcceptAsync를 명시적으로 호출해줘야
OnAcceptCompleted가 실행됩니다.
즉, AcceptAsync는 일종의 입장 허락의 개념이라고 생각하시면 됩니다.
그 전에 접속을 희망한 클라들은 입장 대기를 하고 있겠죠.

코드를 보면 OnAcceptCompleted를 호출해서 입장 관련 처리를 다 끝낸 다음,
마지막에 RegisterAccept를 다시 호출해서 다음 입장을 받아주기 때문에
동시에 여러 쓰레드가 OnAcceptCompleted를 실행할 수 없습니다.
image
물론 Listener Init 코드에서 위의 RegisterAccept를 여러 번 호출하게 수정을 하면
말씀하신 상황이 일어날 수 있겠죠.
(실제로 큰 규모 MMO에선 동시에 입장이 몰릴 경우 대비해 RegisterAccept 횟수를 늘려놓긴 해야 합니다)
그렇다 하더라도 항상 Lock이 필요하진 않고 [공유해서 사용하는 데이터가 있는지]가 핵심입니다.
image
그런데 위 함수에서 딱히 쓰레드끼리 공유해서 사용하는 데이터가 없기 때문에
굳이 동기화 처리를 하지 않아도 무방합니다.

(_sessionFactory가 있긴 하지만 얘는 수정이 없다고 가정)

 

0

dyl

빠른 답변 감사드립니다

그렇다면 msdn 설명 처럼..
Accepting connections asynchronously gives you the ability to send and receive data within a separate execution thread. Before calling the AcceptAsync method, you must call the Listen method to listen for and queue incoming connection requests.

이 글에서 처럼 클라에서 온 애들을 '큐'에 일단 동시 발생 되지 않도록 정렬(동시 두 함수가 실행되지 않게)하여 모아 놓고 AcceptAsync 를 통해 정렬되어진 대기하고 있는 것들을 하나씩 pop 해와서 receive 처리를 하기 때문에

클라에 대한 처리가 args 가 하나만 있을때는 OnAcceptCompleted 이 함수는 한번에 하나씩만 실행 가능하다 라고 이해하면 될까요?

https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.acceptasync?view=netframework-4.7.2&f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(System.Net.Sockets.Socket.AcceptAsync)%3Bk(TargetFrameworkMoniker-.NETFramework%2CVersion%253Dv4.7.2)%3Bk(DevLang-csharp)%26rd%3Dtrue

1

Rookiss

네 그렇습니다.
애당초 넘겨준 args에 접속 클라에 관한 중요 정보를 세팅하기 때문에
아직 완료되지 않은 args를 재사용하면 무시무시한 일이 일어납니다.

TLS 질문드립니다.

0

43

2

SpinLock과 컨텍스트스위칭에 대해 질문 남겨요.

0

48

2

Unity Span

0

76

2

XML, Dll 차이점

0

105

2

Session 질문입니다

0

80

1

Write Read 커서 키워드

0

76

1

더미 클라이언트 수에 따른 OnDisconnect 발생

0

70

2

네트워크 Send 전담 스레드 배치

0

98

2

UnhandledException 으로 서버 터지는 경우

0

86

2

컨텐츠 단, 엔진 단

0

106

1

질문 있습니다

0

77

2

C# 게임서버 3D MMORPG

0

147

2

유니티6 버전

0

98

2

receive하는 부분과 send하는 부분의 차이

0

134

2

커서의 위치의 중요성

0

103

2

C++ 전혀 모르는데 C# 서버

0

170

2

강의에 질문이 있습니다

0

86

2

멀티스레드 이해도 질문

0

95

1

500 vs 500

0

130

3

OnAcceptHandler 액션 함수

0

61

1

이 정도 서버의 객관적인 수준이 궁금합니다.

0

193

2

36. Serialization #3 에서 string (name) 코드 수정 질문

0

83

2

외부 컴퓨터와의 통신 방법이 궁금합니다

0

106

1

스핀락 질문.

0

110

2