하루에 한 문제
Blocking-NonBlocking-Synchronous-Asynchronous 본문
SSAFY수업을 들으면서 몇 번 정도 들어서 어느정도는 알고있는것 같은데 명확하게 설명을 하라고 하면 잘 못할정도라서... 한번 정리를 하고 넘어갈려고 썻음ㅎ
I/O 작업
- I/O 작업은 Input/Output의 약자.
- 주로 파일 입출력을 다룰 때, 흔히 볼 수 있다.
- Ex) 두 대 이상의 컴퓨터끼리 서로 네트워크를 통해 통신을 한다고 가정할 때, 한 컴퓨터에서 출력(send)을 하고 다른 한 컴퓨터에서 입력(read)을 받는 과정을 통해 통신할 수 있다.
- I/O 작업은 User Level에서 직접 수행할 수 없고, 실제 I/O 작업을 수행하는 것은 Kernel Level에서만 가능하다.
- User Process, Thread는 커널에게 요청하고 작업 완료 후, 커널이 반환하는 결과를 기다릴 뿐이다.
Blocking Model
Blocking & Non-Blocking는 프로그램의 실행하는 순서 관점에서 이해를 하면 좀 더 쉽게 이해할 수 있다.
가장 기본적인 I/O 모델로, 리눅스에서 모든 소켓 통신은 기본 blocking으로 동작한다.
I/O 작업이 진행되는 동안 유저 프로세스는 자신의 작업을 중단한 채 대기하는 방식이다.
위의 그림처럼
- 유저는 커널에게 read 작업을 요청.
- 데이터가 입력될 때까지 대기.
- 데이터가 입력되면 유저(커널->유저)에게 결과가 전달되어야만 유저 자신의 작업에 비로소 복귀할 수 있다.
즉 데이터가 입력될 때까지 CPU제어권을 넘겨주는 것이다!! (아무것도 못함)
-> 자원이 낭비된다
C언어의 scanf를 생각해보면 쉽다! ( 사용자가 입력할 때 까지 대기)
Non-Blocking Model
위와 같은 blocking 방식의 비효율성을 극복하고자 도입된 방식이다.
I/O 작업이 진행되는 동안 유저 프로세스의 작업을 중단시키지 않는 방식이다.
- 유저가 커널에게 read 작업을 요청.
- 데이터가 입력되었든 입력되지 않았든 요청하는 그 순간, 바로 결과가 반환된다.
- 이때, 입력 데이터가 없으면 입력 데이터가 없다는 결과 메시지를 반환한다.
- 입력 데이터가 있을 때까지 1~2번을 반복.(2번에서 결과 메시지를 받은 유저는 다른 작업 진행이 가능하다.)
- 입력 데이터가 있으면 유저(커널->유저)에게 결과가 전달된다.
- 이 경우 I/O의 진행시간과 관계가 없기 때문에(대기X) 어플리케이션에서 작업을 오랜 시간 중지하지 않고도 I/O 작업을 진행할 수 있다.
- 그러나 반복적으로 시스템 호출이 발생하기 때문에 이 경우 역시 자원이 낭비된다.
Synchronous (동기)
Synchronous & Asynchronous은 결과물을 돌려받는 시점에 초점을 두면 좀 더 쉽게 이해를 할 수 있다.
- Thread1이 작업을 시작 시키고, Task1이 끝날 때 까지 기다렸다 Task2를 시작한다.
- 작업 요청을 했을 때 요청의 결과값을(return)을 직접 받는다.
- 요청의 결과값이 return값과 동일하다
- 호출한 함수가 작업 완료를 신경쓴다.
Asynchronous (비동기)
- Thread1이 작업을 시작 시키고 완료를 기다리지 않고 Thread1은 다른 일을 처리한다.
- 작업 요청을 했을 때 요청의 결과값(return)을 간접적으로 받는다.
- 요청의 결과값이 return값과 다를 수 있다.
- 콜백을 통한 처리가 비동기 처리라고 할 수 있다.
- 호출된 함수(callback 함수)가 작업 완료를 신경쓴다.
Synchronous/Asynchronous , blocking/non-blocking 차이점은?
- 사실 이렇게 보면 Synchronous와 blocking, Asynchronous와 blocking는 거의 똑같다고 생각이된다.
- 이 두 그룹의 차이점은 관심사가 다르다는 점이다.
blocking / non-blocking
- 이 그룹의 관심사는 호출되는 함수가 바로 return되느냐 마느냐이다.
- 호출된 함수가 바로 return해서 호출한 함수에게 제어권을 넘기고 호출한 함수가 다른일을 할 수 있다면 non-blocking
- 호출한 함수에게 제어권을 넘겨주지 않고 대기하게 만든다면 blocking이다.
Synchronous/Asynchronous
- 이 그룹의 관심사는 호출되는 함수의 작업 완료여부를 누가 신경쓰느냐가 관심사이다.
- 호출되는 함수에게 callback을 전달해 호출되는 함수의 작업이 완료되면 호출되는 함수가 전달받은 callback을 실행하고, 호출한 함수는 작업 완료 여부를 신경쓰지 않는다면 Asynchronous이다.
- 호출하는 함수가 호출되는 함수의 작업 완료 후 return을 받거나 호출되는 함수로부터 바로 return을 받더라도 작업 완료 여부를 호출한 함수 스스로 확인하며 신경 쓴다면 Synchronous이다.
Synchronous/Asynchronous , blocking/non-blocking 조합
이들에 대해 공부하다 보면 아래와 같은 그림을 마주치게 될것이다!
blocking + Synchronous , non-blocking+Asynchronous
blocking + Synchronous
- 결과가 나올 때 까지 기다렸다가 return 값으로 결과를 전달.
non-blocking+Asynchronous
- 작업 요청을 받아서 별도의 프로세서에서 진행하게 하고 바로 return(작업 끝)한다.
- 결과는 별도의 작업 후 간접적으로 전달(callback)한다.
non-blocking + Synchronous
- 결과가 없다면 바로 return한다.
- 결과가 있으면 바로 결과를 return 한다. (결과가 생길때까지 계속 완료 되었는지 확인)
blocking + Asynchronous
- 호출되는 함수가 바로 return하지 않고, 호출하는 함수는 작업 완료 여부를 신경쓰지 않는다.
- (이 조합은 사실 이점이 없어서 일부러 이 방식을 사용하진 않는다고 한다.)
- (의도하지 않게 blocking+Async로 동작하는 경우가 있다고는 한다. 이는 non-blocking+Async를 추구하다 의도가 변질되어버림... 대표적으로 Node.js + MySQL 조합이라고 한다.)
마지막으로 예시를 한번 들어보자
상황: 급하게 알아야 하는 답을 누군가에게 물어봐야하는 상황
- 전화로 물어봐서 즉답을 얻는다. = 동기 요청처리
- 이메일로 물어보고 메일 송신을 완료(return)했지만 답은 언제 올지 모른다. = 비동기 요청처리
- 전화를 했는데 상대방이 너무 바빠 전화를 받지 않음
전화를 받을때까지 계속 대기 = 동기 + 블록킹 - 전화를 했는데 안 받음
끊었다가 나중에 다시 전화함
계속 반복했다가 어느 순간에 받아서 답을 얻음 = 동기 + 논블록킹
참고
velog.io/@wonhee010/%EB%8F%99%EA%B8%B0vs%EB%B9%84%EB%8F%99%EA%B8%B0-feat.-blocking-vs-non-blocking
nesoy.github.io/articles/2017-01/Synchronized
homoefficio.github.io/2017/02/19/Blocking-NonBlocking-Synchronous-Asynchronous/
'CS > 네트워크' 카테고리의 다른 글
크로스 브라우징 (0) | 2021.04.14 |
---|---|
로드 밸런싱 (0) | 2021.04.01 |
주소창에 naver.com을 치면 일어나는 일 (1) | 2021.03.31 |
UDP (1) | 2021.03.31 |
TCP ( 흐름 제어, 오류 제어) (0) | 2021.03.31 |