삽질의 현장/- 네트워크 프로그래밍

#022_Window_Network_비동기 소켓 입출력 모델

shovelman 2015. 10. 13. 14:39


안녕하세요 삽잡이입니다.


이번시간에는 비동기 입출력 모델에 대해서 알아보려고합니다.


우리는 이전시간까지 

쓰레드, Select, WSAAsyncSelect, WSAEventSelect 모델에 대해서 알아봤었습니다.

사실, 쓰레드를 제외한 세 모델들은 모두 '비동기'와 관련성이 있는 모델들은 아닙니다.


위에 모델들에서 붙은 WSA는 

Window Socket의 2.0 이상 버전에서 만들어 졌음을 명시하는 줄임말입니다.

즉, 2.0대 이상의 소켓에서 핵심은 바로 '비동기'입니다.

그래서 Window Socket Async를 붙였습니다. 단지 표시를 한 것이지요...

기존의 함수들은 비동기 방식의 모델이 없었지요... 2.0 대 부터 만들어졌구요...


아무튼... 2.0 버전 이상부터 만들어진 함수는 WSA가 붙기 때문이지

WSAAsyncSelect, WSAEventSelect 모델들은 비동기 IO 모델이 아닙니다.


오늘부터 배울 모델들이 비로소 

'비동기' 방식으로 입출력하도록 만들자는 취지에서 만들어진 모델들이다 이겁니다...


동기와 비동기는 이전에 언급했던 적이 있습니다.

어떤 여러개의 task, job에 대해서 어떤식으로 처리할 것이냐에 따라서

'동기'와 '비동기'로 나뉠 수 있습니다.


즉, '단 하나'의 작업이라면 동기, 비동기 용어를 사용할 수 없다 이겁니다.

적어도 여러개의 작업이 있을 때 그 작업을 하나씩 '순서대로' 처리하면 동기적,

동시에 '순서 없이' 처리하면 비동기적이라고 할 수 있습니다.


동시 다발적으로 작업이 진행되는 비동기적 작업 상황에서 

우리는 오직 '쓰레드'만을 통해 일을 처리했었습니다.

비동기 하면 'thread'가 떠올랐다 이겁니다... 


하지만, 비동기 방식은 thread만이 있는 것이 아닙니다.

오늘 배울 모델들이 실질적으로 '비동기'모델이라고 볼 수 있는 것입니다.


비동기 모델에는 크게 두 가지가 있습니다.

Overlapped I/O 모델과 IOCP I/O 모델이 있습니다.


Overlapped 모델은 두가지로 또 나뉠 수 있습니다.

바로, Event Kernel Object를 사용하는 모델과 Completion routine을 사용하는 모델입니다.

Overlapped 이라는 단어는 '겹쳐서 일어나는 사건'이라는 '중첩'의 뜻입니다.

즉, 작업이 겹쳐진다는 뜻입니다.


컴퓨터에서 일반적인 용어로 '비동기'라는 용어를 MS에서 'Overlapped'라고 부르는 것일 뿐입니다.

비동기라는 것은 말 그대로 동기적이지 않다는 뜻입니다.

동기적이라는 뜻은 여러개의 작업이 순차적으로 수행되지 않는다는 뜻이구요.

따라서, 비동기적이라는 말은 '여러개의 작업이 동시에 수행될 수 있는'이라는 뜻입니다.

그런데 Windows 에서는 여러 작업들이 겹쳐서 일어나는 작업을

Overlapped 즉, 중첩 작업이라고 부른다는 것입니다.


결과적으로 Overlapped 모델은 우리나라 말로 '비동기 IO 모델'이라고 말할 수 있다는 것이지요...

뭐... '비동기'라는 뜻은 MS 에서만 Overlapped 라고 부르고 그 외 다른 곳에서는 async라고 부르지요...


자... 아무튼 Overlapped 모델에서 I/O 함수들은 Overlapped들을 필요로 합니다.

이 Overlapped 는 크게 WSASend(), WSARecv()

그리고 결과치를 알아내는 GetOverlappedResult() 함수등에서 사용합니다.


사실 우리가 모델들을 분류해서 나눠보라고 하면 크게 3부류로 나눌 수 있습니다.



바로, '쓰레드 모델', 'Flag 모델', 'Overlapped 모델'로 나눌 수 있다 이겁니다.


쓰레드 모델은 어플리케이션에서 쓰레드를 만들어 데이터를 주고 받습니다.

쓰레드 모델에서는 OS가 아닌 어플리케이션에서 신호 까지 모두 감지를 해야합니다.

그렇지 않다면, 데이터가 들어왔는지 오지 안았는지 모른다 이겁니다...

즉, 어플리케이션이 모든 일을 담당한다고 할 수 있습니다.


Flag 모델은 OS에서 신호를 감지하고 신호를 보내주면,

그 신호에 따라 어플리케이션에서 동작을 하는 모델입니다.


Overlapped 모델은 Flag 모델보다는 쓰레드 모델과 비슷합니다.

사실 내부적으로 OS가 쓰레드를 생성시켜 동작시키기 때문입니다.

쓰레드를 쓰레드 모델에서 처럼 여러개 띄우는 것이 아니라, OS가 쓰레드를 띄운다는 것입니다.

즉, I/O 작업에 대한 쓰레드를 OS가 생성시킨다 이겁니다.


동작을 먼저 한다는 것입니다.

Flag 모델과 차이점은 Flag 모델은 '선 flag 후 동작'인데,

Overlapped 모델은 '선 동작'을 우선 한다 이겁니다.

그러면 OS에서 동작을 수행하기 위한 쓰레드를 돌려가면서 동작을 해줍니다. 


정리하자면, thread 모델은 모든 것을 어플리케이션이 동작합니다.

그래서 따로 처리해야할 작업이 없습니다.

비효율적이라도 모든 일을 어플리케이션에서 해주니깐 말입니다...


Flag 모델은 신호만은 OS가 해준다는 것입니다.

그리고 동작은 어플리케이션이 하고 말입니다.

동작은 어플리케이션에서 하니까 동작의 성공 유무는 어플리케이션에서 알겠지요...


Overlapped 모델은 동작을 먼저 어플리케이션에서 호출해주면,

그 동작을 OS에 있는 쓰레드가 수행해주는 것입니다.

동작을 시작만 해두고 실제 동작은 OS가 해준다는 것입니다.

시작하는 것은 명령만 때려두면 되니 엄청 편하겠군요...

Flag 모델은 마무리 동작을 어플리케이션이 다 해줘야되는데 말입니다...

Overrlapped 모델은 OS가 수행해주고요...


그런데 작업이 완료됬다는 시점을 어플리케이션에서 알아야합니다.

따라서 Overlapped 모델에서는 '완료보고'가 중요합니다.

OS가 일을 완료했다는 것을 어플리케이션에 알려주는 것입니다.


완료 보고를 받는 방식에 따라서

Overlapped (Event, Completion routine), IOCP 와 같은 방식으로 나뉩니다.

즉, 동작 방식은 똑같은데 수행하라고 명령을 시키키고 완료된 결과를 알려달라는..

즉, 완료 보고를 받는 방식이 다른 것입니다.


여담으로,

다른 프로그램 영역에서는 대부분 쓰레드 방식을 '동기 방식'이라 부르고,

Overlapped 방식을 '비 동기 방식'이라고 부릅니다.


쓰레드끼리 비교했을 때는 비동기 방식이 맞지만 

쓰레드 하나만을 놓고 보면 동기적인 함수, 비 동기적인 함수 호출 유무로 방식을 구분할 수 있습니다.

즉, blocking / non bloking 함수를 쓰는 형태로 종류가 나뉜다 이겁니다.


그런데 주의해야할 사항은

쓰레드 방식만을 사용한다고 반드시 블로킹 방식이라고,

overlapped 방식만을 사용한다고 반드시 넌 블로킹 방식이라고 할 수 없습니다.

즉, blocking이 동기, non blocking이 비동기가 아니란 말입니다.


단지, 블록킹, 넌 블록킹이란 I/O 작업에서 차이가 나는 것입니다.

I/O 함수들이 자기 목적을 다 하지 않더라도 return을 한다면 non blocking이라는 것입니다.

이건 blocking 모델, non blocking 모델라고 하는 것이 아닌,

'모드'라고 합니다. 소켓 모드 말입니다...

결과적으로 소켓 모드에는 두가지 모드가 있는 것이지요...

blocking 모드와 non blocking 모드 말입니다...


어찌됬건, 다음 시간에는 overlapped 모델 방식을 알아볼 것입니다.

'선 동작'을 수행하는 함수들의 종류가 있는 I/O 모델 방식 말입니다.

그리고 이 함수들을 모두 다 '비동기 함수'라고 부르는 것입니다.


그럼 오늘은 여기까지 하도록 하겠습니다.

이상 삽잡이였습니다!