• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

RegisterSend를 하나의 스레드만 수행하는 이유가 궁금합니다.

22.03.08 12:04 작성 조회수 200

1

큐에서 데이터를 꺼내는 작업 자체가 여러 스레드가 동시에 들어가도 의미가 없거나 wsasend가 스레드 안전하지 않아서 그런건가요? recv도 그렇고 send도 그렇도 하나의 세션에 대한 본질적인 작업은 사실상 하나의 스레드만 수행할 수 있다고 이해하면 되는걸까요?(사실상 여러 스레드가 접근해도 실질적인 세션의 공유자원(버퍼 등등)에 대해 순차적으로 접근할 수 있으므로 )

답변 1

답변을 작성해보세요.

3

네 WsaSend가 쓰레드 안전하지 않은 이슈도 있고요.
다만 Recv/Send 모두 하나의 쓰레드만 수행할 수 있느냐?는 애매한 문제입니다.
Recv의 경우에는, 확실히 1개의 클라에서 데이터를 보내니 굳이
단일 Session에 대해 멀티쓰레드로 Recv 처리할 이유가 없습니다.
Send의 경우에는, 비록 WSASend를 락잡고 한 번에 하나씩만 하는 것은 맞지만
이전에 보낸 Send가 완료되기 전에 또 Send를 할 수 없느냐? 는 논란의 여지가 있는데
컨텐츠를 만들다보면 이리 저리서 동일한 Session에 대해 Send를 할 일이 생기기 때문이죠.

이전에 Send한 데이터가 다 전송되지 않았을 때 대기를 타야 한다면
반응 속도에서 조금 손해를 보지만, MMO처럼 아주 많은 Session에 대해 처리가 수월해집니다.
그러면 데이터 처리가 완료되어 OnSendCompleted가 호출될 때 그 사이 추가로 
요청된 Send 데이터가 있는지 판별해서 또 전송하면 되겠죠.

반대로 이전에 Send한 데이터가 다 전송되기 전에도 또 Send가 가능하다면,
반응 속도에서 이점이 있지만, 반대로 네트워크 7 Layer상의 헤더 정보가
덕지덕지 붙는 것을 감안하면 최고의 효율성은 보이지 못할 수도 있습니다.
그리고 SendEvent를 1개만 두면 안되고 보낼때마다 새로 만들야 합니다.

 

cckiz153님의 프로필

cckiz153

질문자

2022.03.08

얕은 질문에도 상세하게 답변해주셔서 정말 감사드립니다..! 정말 죄송하지만 말씀해주신 Send한 데이터가 다 전송되지 않았을 때 대기한다는 방식이 이번 코드의 방식이라고 이해하면 될까요? SendQueue에 삽입만 하고 실질적인 Send는 하나의 스레드가 수행하도록 한 후 나머지는 대기함으로써 반응성은 조금 떨어질 수 있어도 Session 처리가 수월해진다. 제가 이해한게 맞는지 궁금합니다.. ㅎㅎ

저 그리고 또 궁금한게 지금 방식보다 반응이 빠른 방식이 있을지 궁금합니다. 지금처럼 하지 않는다 해도 WSASend에는 결국 동기화 처리를 해야 되는데 지금만큼 예쁜 다른 방식이 있는지 궁금합니다.

얕은 질문에도 상세하게 답변해주셔서 정말 감사드립니다..! 정말 죄송하지만 말씀해주신 Send한 데이터가 다 전송되지 않았을 때 대기한다는 방식이 이번 코드의 방식이라고 이해하면 될까요? 

-> 네 잘 이해하셨습니다.

저 그리고 또 궁금한게 지금 방식보다 반응이 빠른 방식이 있을지 궁금합니다.

-> WSASend 호출은 Lock을 걸고 하는 것까지는 어쩔 수 없지만,
SendQueue를 두지 않고 보내는 족족 WSASend로 바로 때려주는 방식이 있습니다.
(SendEvent도 보낼때마다 새로 생성)


cckiz153님의 프로필

cckiz153

질문자

2022.03.08

감사드립니다 ! 저 그리고 혹시 비동기 입출력 시에 overlapped 구조체와 더불어서 wsabuf는 입출력 완료시까지 보존해야 돼서 지역변수로는 잘 쓰지 않는다고 들었는데 문제가 없는지 궁금합니다. sendbuffer가 레퍼런스 카운팅이 되니까 WSABUF 자체는 문제가 없는 것인가요? 한번에 질문드린다는게 자꾸 따로 따로 올려서 정말정말 죄송합니다 ㅠㅠ

버퍼는 절대 건드리면 안 되고 유지시켜줘야 하지만,
wsabuf는 상관없습니다. (wsabuf.buf가 중요)
강의에선 힙영역에 올라와 있는 버퍼를 쪼개서 sendBuffer로 사용하고,
입출력 완료까지 유지되도록 RefCount 관리를 해주고 있기 때문에
버퍼의 안전성이 보장됩니다.