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

열공자!님의 프로필 이미지

작성한 질문수

[게임 프로그래머 입문 올인원] C++ & 자료구조/알고리즘 & STL & 게임 수학 & Windows API & 게임 서버

Overlapped

Select와 Overlapped의 차이에 대해 좀 헷갈리는 부분이 있습니다.

해결된 질문

23.06.29 19:48 작성

·

509

0

Overlapped 방식은 비동기 + 논블로킹 이고 이전 예제 WSASelectEvent를 이용한 예제는 동기 + 논블로킹 으로 이해 했습니다.


Overlapped의 로직 흐름은 while문 진입 후 Event방식의 경우 WSARecv의 반환값이 SOCKET_ERROR일때 WSAGetLastError()가 WSA_IO_PENDING이라면 Sleep 혹은 WSAWaitForMultipleEvents으로 대기하다가 콜백방식이면 깨워서 처리, 이벤트방식이면 시그널되었으므로 이후 다음 코드 실행


Select의 로직 흐름은 while문 진입 후 WSAWaitForMultipleEvents로 대기 후 시그널되면 인덱스정보로 세션의 위치를 알아낸 후 해당 세션의 소켓을 통해 NetworkEvent를 확인해서 Accept인지 Recv플래그를 통해 적절한 처리


이렇게 정리하고 나니 결국 Overlapped는 Recv를 먼저 실행한 후 대기하는 것이고 Select는 대기한 후 Recv하는 것이구나 라는 생각이 들었고,

처음에 보여주신 블로킹/논블로킹, 동기/비동기에 관한 그림으로 볼 때 Select와 Overlapped 모두 Sync-NonBlocking과 같이 동작하는게 아닌가 하는 생각이 들었습니다.

 

왜냐하면 INFINITE로 두면 반환할때까지 Blocking 방식처럼 동작할 것이라고 생각했고, INFINITE가 아닌 Timeout을 주면 주기적으로 확인한다는 것이므로 Sync-NonBloking처럼 동작한다고 생각했습니다.

 

제가 생각한 것이 맞는지 궁금합니다.

답변 1

0

인프런 AI 인턴님의 프로필 이미지

2023. 06. 30. 19:51

안녕하세요, 인프런 AI 인턴이에요. Select와 Overlapped의 차이에 대해 설명해 드릴게요.

Select와 Overlapped 모두 비동기 통신을 위한 방식이지만, 동작 방식이 조금씩 다릅니다.

Select는 입력 가능한 소켓들의 집합을 지정하고, 해당 소켓을 감시하면서 입력 가능한 상태인지 주기적으로 확인합니다. 그리고 입력 가능한 상태가 되면 그 소켓을 별도의 처리로 가져옵니다.

Overlapped는 비동기 I/O를 이용하여 데이터를 받거나 보낼 때, I/O 작업이 완료되면 알림을 받아 다음 작업을 처리합니다. I/O 작업이 완료되기 전에 다른 작업을 할 수 있으며, 작업이 완료되면 알림을 받아 처리하는 방식입니다.

이러한 동작 방식으로 인해 Select는 입력 가능한 소켓을 선택해서 데이터를 받아오는 반면, Overlapped는 I/O 작업이 완료되었을 때 데이터를 받아옵니다.

이해를 돕기 위해 블로킹/논블로킹과 동기/비동기의 개념과는 조금 다르게 사용되기 때문에, 동시에 Sync-NonBlocking으로 동작하는 것은 아닙니다.

또한, INFINITE로 대기하면 반환할 때까지 Blocking 방식으로 동작하고, Timeout을 주면 주기적으로 대기하던 시간이 경과하면 반환하는 방식으로 동작합니다.

더 자세한 내용이 필요하시다면, 관련 문서나 강의를 참고하시거나 구체적인 질문을 알려주시면 더 도움을 드릴 수 있을 것 같아요. 이해에 도움이 되었기를 바랄게요. 다른 질문이 있으시면 언제든지 물어보세요!

열공자!님의 프로필 이미지
열공자!
질문자

2023. 07. 01. 10:04

이해를 돕기 위해 블로킹/논블로킹과 동기/비동기의 개념과는 조금 다르게 사용되기 때문에, 동시에 Sync-NonBlocking으로 동작하는 것은 아닙니다.

 

이 부분이 어떤 의미로 말씀하신건지 잘 이해되지 않네요..

제가 헷갈리는 부분은 정확히 이 부분입니다

Overlapped 예제의 경우 WSA_IO_PENDING상태일때 SleepEx 분기로 진입하고, SleepEx 함수는 정해진 시간동안 대기(INFINITE의 경우 블로킹 함수처럼 작동하여 TimeOut을 주는 걸로 가정)

SleepEx는 Alertable wait 함수로 APC큐에 '잡'이 있으면 깨어나서 일을 하는 함수라고 이해했고 여기서 '잡'은 콜백함수 호출을 의미한다고 이해했습니다

 

그렇다면 매 루프마다

<Overlapped 방식>

=SleepEx로 잡이 있는지 확인한다

=잡이 있으면 깨어나 잡을 처리

 

<Select 방식>

=WSAWaitForMultipleEvents로 시그널되었는지 확인한다

=시그널되었으면 플래그를 확인하고 적절한 처리

 

정리하면 매 루프를 도는것은 두 방식 모두 공통적이지만 대기하는 시점에서 Overlapped는 알림을 받는 것이고, Select는 직접 확인하는 것의 차이라고 이해하는 게 좋을까요?

 

이게 맞다면 매 순간 SleepEx 분기로 들어서는게 '확인한다' 라고 헷갈렸던게 문제였나봅니다 ㅎㅎ