동기(synchronous)와 비동기(asynchronous) / 블로킹(blocking)과 논블로킹(non-blocking)
1. 동기(Synchronous)와 비동기(Asynchronous) 개념
- 동기는 요청과 그 결과가 동시에 일어난다는 뜻이며,
- 다시 말하면, 어떤 객체 또는 함수 내부에서 다른 함수를 호출했을 때 이 함수의 결과를 호출한 쪽에서 처리하면 동기입니다.
- 비동기는 요청과 그 결과가 동시에 일어나지 않는다는 뜻이며,
- 동기와 달리 어떤 객체 또는 함수 내부에서 다른 함수를 호출했을 때 이 함수의 결과를 호출한 쪽에서 처리하지 않으면 비동기입니다.
1) 동기의 예
일반적으로 사용하는 함수들은 대부분 동기적 방식입니다.
C언어의 scanf()와 Java의 Scanner 객체의 next()메서드 같이 사용자의 입력을 받는 함수들이 그 예입니다.
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
sc.nextInt() 결과 사용자가 입력을 하면, 그 값은 num이라는 변수에 담깁니다.
즉, nextInt() 메서드를 호출하고 그 결과를 자신이 직접 처리 했습니다.
따라서 위의 코드는 동기적 방식이라 할 수 있습니다.
2) 비동기의 예
다음은 JS의 setTimeout() 함수이며, 비동기 방식의 예입니다.
setTimeout( foo, 3000);
function foo(){
console.log("2");
}
console.log("1");
setTimeout() 함수를 호출하면 3초 뒤에 foo() 함수가 수행되는 코드입니다.
setTimeout() 함수를 호출한 후 3초라는 시간이 흘러야 foo() 함수가 수행되며, 이 시간 동안 프로그램은 다음 코드를 읽기 때문에, 위 코드는 콘솔에 1, 2 순서로 출력이 됩니다.
여기서 foo()함수를 setTimeout()함수의 콜백( callback )함수라고 합니다.
콜백 함수란 비동기 방식에서 어떤 수행이 완료되었을 때( event가 발생했을 때 ) 수행해야 할 함수를 의미합니다.
이처럼 비동기 방식에서는 함수를 호출한 쪽에서 수행 결과를 직접 처리하지 않고 콜백 함수를 통해 수행 결과를 처리합니다.
이처럼 동기와 비동기는 수행의 결과를 함수를 호출한 쪽에서 직접 처리하느냐, 아니면 다른 곳에서 처리하느냐의 차이로도 볼 수 있습니다.
2. 블로킹(Blocking)과 논블로킹(non-blocking)
- 블로킹은 자신의 수행결과가 끝날 때까지 제어권을 갖고 있는 것을 의미합니다.
- 논블로킹은 자신이 호출되었을 때 제어권을 바로 자신을 호출한 쪽으로 넘기며, 자신을 호출한 쪽에서 다른 일을 할 수 있도록 하는 것을 의미합니다.
동기와 블로킹 / 비동기와 논블로킹은 비슷해 보이지만 다른 개념입니다.
이 글의 주제로 구글링을 하다 보면 위의 그림을 많이 볼 수 있습니다.
일반적으로 동기와 블로킹 / 비동기와 논블로킹의 조합이 익숙하며, 사실은 동기와 비동기를 소개할 때 사용했던 예제들은 그 내부에 blocking와 non-blocking 개념이 깔려있습니다.
1) 블로킹
동기 예제 코드에서는 사용자가 입력할 때까지 프로그램은 어떠한 동작도 수행하지 않습니다.
즉, 사용자가 입력할 때까지 제어권은 nextInt()메서드에게 존재하며, 사용자가 입력을 해야만 제어권이 넘어가서 이후의 코드가 수행됩니다.
이처럼 수행 결과가 끝날 때까지 제어권을 갖고 있는 것이 blocking 방식입니다.
2) 논블로킹
비동기 예제 코드의 수행 결과는 1, 2가 순서대로 출력됩니다.
그 이유는 setTimeout(foo, 3000) 함수를 호출할 때 제어권을 바로 반납하기 때문입니다.
즉, 3초 뒤에 foo() 함수가 실행이 되지만, 제어권을 반납했기 때문에 바로 다음 코드인 console.log("1")가 수행이 됩니다.
그리고 나서 3초라는 시간이 흘렀다는 이벤트가 발생하여 콜백 함수인 foo() 함수가 수행이 되는 것이죠.
이처럼 제어권을 바로 반납하는 방식을 non-blocking 방식이라 합니다.
이상으로 동기와 비동기, 블로킹과 논블로킹에 대해 알아보았습니다.
여러 조합을 사용할 수 있지만, 이 글에서는 동기+블로킹 , 비동기+논블로킹에 대해서만 알아보았습니다.
그 밖의 조합에 대해서는 경험이 부족해서 예제를 만들 수가 없었습니다...
이 글의 목표는 동기와 비동기, 블로킹과 논블로킹에 대한 개념적 이해에 중점을 두도록 했습니다 !
[ 참고자료 ]
https://homoefficio.github.io/2017/02/19/Blocking-NonBlocking-Synchronous-Asynchronous/