2018년 5월 23일 수요일

Blocking, Non-Blocking, Synchronous, Asynchronous.

면접에서 non-blocking과 asynchronous의 차이점을 질문받았었는데 제대로 답변하지 못했다. Blocking와 non-blocking 차이점을 말씀드린 후, synchronous와 asynchronous의 차이점을 말씀드리는 편이 나았을 것 같다. 아니면 blocking과 non-blocking의 차이점을 설명해보라는 질문이었다면 좀 더 나은 상황(?)이었을 것이다.

다 알고있다고 생각했던 개념이었지만 막상 설명하려고 하면 말문이 막히는 개념.. 정리해보고자 한다. 아래 링크의 자료가 가장 큰 도움이 되었다.
https://www.slideshare.net/namhyeonuk90/tcp-ip-io-model


Blocking vs Non-Blocking

Blocking, non-blocking은 호출한 입장에서 구분지을 수 있다. 함수(system call)를 호출했을 때 처리 결과와 무관하게 바로 리턴 받아 제어권을 갖을 수 있으면 non-blocking. 일반적인 함수 호출에서처럼 작업이 끝날 때까지 대기해야 하면(작업이 끝날 때가지 리턴이 없음) blocking.


Synchronous vs Asynchronous

Synchronous, asynchronous는 함수의 처리방식에서 구분지을 수 있다. 작업 완료 여부를 누가 신경쓰냐에 대한 것으로 함수의 작업 완료 후 리턴을 기다리거나 바로 리턴을 받더라도 작업 완료 여부를 스스로 확인하면 synchronous. 작업을 요청해놓고 다른 일을 하다가 해당 작업이 완료되면 완료되었음을 통지 받고 그에 따른 처리를 하는 모델은 asynchronous. (통지 방식; 델리게이트, 퓨처, 프로미스, 콜백)

→ 결과 형태의 구분으로 non-blocking과 asynchronous를 구분하기도 하고, 의견은 다양하다.

! 추가로 I/O 모델과 I/O 이벤트 통지 모델에 대한 정리. 마찬가지로 위 슬라이드 쉐어 링크에 자세히 정리되어 있다.

I/O

I/O에서 대화의 주체는 커널과 프로세스다. I/O 작업은 사용자 레벨에서 할 수 없기 때문에 프로세스는 커널에게 I/O를 요청해야 한다. 그리고 커널은 프로세스에게 I/O 상황을 응답(통지) 한다.


Blocking I/O

Blocking 모델로 클라이언트 별로 스레드를 생성해서 처리하는 방식이 일반적이다. 클라이언트 수가 많아질 수록 많은 스레드의 생성을 요구하기 때문에 스레드 생성 비용, 스레드 간 스위칭 비용 등 성능상 비효율적이다.


Non-Blocking I/O

I/O 작업을 진행하는 동안 유저 프로세스의 작업을 중단하지 않는다. selector나 poll에 여러 소켓을 바인딩 시킨 후 하나의 채널(스레드)에서 관리한다.


I/O 이벤트 통지 모델

Non-Blocking I/O의 개선 버전. 마찬가지로 하나 또는 적은 스레드로 다수의 클라이언트를 제어할 수 있다. I/O 처리를 할 수 있는 소켓(또는 fd)를 가려내서 커널이 통지해주는 방식이다.

I/O 이벤트 통지 모델 in Linux

select
이벤트 별로 감시할 소켓을 등록하고, 등록한 소켓에 이벤트가 발생하면 그것을 확인하는 방식으로 동작한다. (fd는 1024개 제한)
→ 자체 event loop를 통해 상태 변경을 확인하기 때문에 Synchronous 방식이며 timeout이 nullptr이면 Blocking, timeout이 지정되어 있으면 Non-Blocking이라 할 수 있다.

epoll
select가 매번 모든 fd를 검사한다면 epoll은 검사할 fd만 등록해 놓으면 커널이 fd를 관리하면서 이벤트 발생 여부를 알려주므로 효율이 좋다. fd 개수 제한은 없다.
→ select와 마찬가지로 Synchronous 방식이며 timeout 인자에 따라 Blocking, Non-Blocking으로 구분된다.

I/O 이벤트 통지 모델 in Windows

WSAAsyncSelect
특정 소켓에 대해 통지 받을 이벤트와 통지 받을 때 사용할 메시지를 지정해주면 이벤트가 생길 때 메시지 큐를 이용해 윈도우 메시지 형태로 통지해주는 방식이다. 소켓 이벤트를 다른 메시지 처리하듯 일관성 있게 처리할 수 있는 장점.
→ 운영체제가 I/O 완료 통지를 해주므로 Asynchronous. WSAAsyncSelect에 지정된 소켓은 Non-Blocking으로 동작이 바뀐다. 따라서 Non-Blocking.

WSAEventSelect
윈도우 메시지 모델이 아니고, 네트워크 이벤트가 발생했을 때 이와 연동시킬 이벤트 오브젝트를 등록하는 방식으로 처리된다.
→ select와 비슷하게 폴링하는 방식이므로 Synchronous. 마찬가지로 WSAEventSelect에 지정된 소켓은 Non-Blocking으로 동작이 바뀐다.

댓글 없음:

댓글 쓰기