Lined Notebook

동기(Synchronous)와 비동기(Asynchronous) / 블로킹(Blocking)과 논블로킹(Non-Blocking)

by HeshAlgo

1. 동기(Synchronous)와 비동기(Asynchronous)

1) 동기(Synchronous) : 요청과 결과가 동시에 일어남

- 어떤 객체 또는 함수 내부에서 다른 함수를 호출했을 때 이 함수의 결과를 호출한 쪽에서 처리

즉, 어떤 객체 또는 함수가 다른 함수를 요청하면 시간이 얼마가 걸리든 요청한 자리에서 결과가 주어져야 합니다.

 

동기 예제

일반적으로 사용하는 함수가 동기적 방식

Java에서는 Scanner 객체의 nextInt() 함수가 예시가 될 수 있습니다.

Scanner scan = new Scanner(System.in);
int num = scan.nextInt();

사용자의 입력을 받고 결과를 num이라는 변수에 저장시킵니다. 위의 코드를 실행하게 되면 입력을 받을때까지 기다리게 되는데

이렇게 요청한 자리에서 시간이 얼마가 걸리든지 결과가 주어져야 합니다.

 

2) 비동기 (Asynchronous) : 요청과 결과가 동시에 일어나지 않음

- 두 주체가 서로의 시작이나 종료시간에 관계 없이 별도의 시작/종료 시간을 가지고 있습니다.

비동기 방식은 함수를 호출한 쪽에서 직접 처리하지 않고 콜백함수를 통해 결과를 처리합니다.

 

※ 비동기 예제

JS코드의 비동기 코드입니다.

setTimeout(foo, 3000)

function foo() {
    console.log("2")	// 3초 후 출력
}

console.log("1")

setTimeout()로 인해 3초 후에 foo()메서드를 호출해 "2"의 키워드를 출력할 것입니다.

이 3초 동안은 foo()메서드를 호출할때 까지 기다리는 것이 아닌 다른 일을 수행합니다. 그래서 다음 코드를 수행하기 위해 "1"을 먼저 출력한 다음 3초가 지나게 되면 "2"를 출력하게 됩니다.

 

여기서 foo()메서드를 setTimeout() 메서드의 콜백(callback)함수라고 합니다.

 

이처럼 동기와 비동기는 함수의 수행 결과를 호출한 쪽에서 직접 처리하느냐 안하느냐의 차이가 있습니다. (작업 여부)

 

2. 블로킹(Blocking)와 논블로킹(Non-Blocking)

1) 블로킹(Blocking)

- 호출된 함수가 자신이 할 일을 모두 마칠 때까지 제어권을 계속 가지고서 호출한 함수에게 바로 돌려주지 않습니다.

동기 예제 코드를 참고하자면 사용자가 입력을 완료할때까지 어떠한 동작도 수행하지 않습니다.

즉, 사용자가 입력할 때 nextInt()메서드가 제어권을 가지고 있어 사용자가 입력을 완료해야만 다음 코드로 넘어갑니다.

이처럼 수행 결과가 끝날때까지 제어권을 가지고 있는 것이 블로킹(Blocking)입니다.

 

2) 논블로킹(Non-Blocking)

- 호출된 함수가 자신이 할 일을 모두 마치지 않았더라도 바로 제어권을 건네주어 호출한 함수가 다른 일을 진행할 수 있도록 해줍니다.

비동기 예제 코드를 참고하자면 수행 결과가 1, 2 이렇게 순서대로 출력되는 모습을 볼 수 있을 것입니다.

그 이유는 setTimeout() 메서드가 호출 되자 마자 제어권을 바로 넘겨 주기 때문입니다.

즉, 3초 후에 foo()메서드가 실행되지만 제어권을 바로 넘겨버리기 때문에 console.log("1")을 먼저 실행합니다.

그러고나서 3초라는 시간이 지났다는 이벤트가 발생하여 콜백 함수인 foo()메서드를 실행합니다.

이처럼 제어권바로 반납하는 것을 논블로킹(Non-Blocking)이라 합니다.

 

블로킹과 논블로킹은 호출되는 함수가 제어권을 바로 리턴하느냐 마느냐가 차이입니다.

즉, 자신이 다른 주체가 작업을 할 때, 자신이 제어권을 가지고 있는지 없는지 볼 수 있습니다.

 

3. 4가지 조합의 예시

1) Blocking + Synchronous (블로킹 + 동기)

fun main() {
    print("출력하고 싶은 메세지를 입력하세요 : ")
    val scanner = Scanner(System.`in`)
    val message = scanner.nextLine()
    println("블로킹 동기")
    println(message)
}

제어권이 scanner의 nextLine()으로 넘어갔기 때문에 println() 함수가 실행이 되지 않습니다. 

입력을 하게 되면 제어권과 결과를 함께 호출한 함수로 전달하기 때문에 한번에 처리가 되고 있습니다.

 

2) Non-Blocking + Synchronous (논블로킹 + 동기)

논블로킹은 다른작업이 있어도 제어권을 가지고 있기 때문에 다른 일 처리 상관없이 자신의 일을 처리하게 됩니다.

그런데 동기는 결과에 관심이 있기 때문에 중간 중간 마다 제어권을 가지고 있는 Application이 결과가 완료 되었는지 호출된 함수에게 물어보게 됩니다.

결과가 완료 되었다면 그 결과를 가지고 바로 처리하게 됩니다. 

 

3) Blocking + Asynchronous (블로킹 + 비동기)

제어권을 가지고 있지 않지만 결과를 바로 처리하지 않는다 

 

4) Non-Blocking + Asynchronous (논블로킹 + 비동기)

 

😶 참고 문헌

https://victorydntmd.tistory.com/8

 

동기(synchronous)와 비동기(asynchronous) / 블로킹(blocking)과 논블로킹(non-blocking)

1. 동기(Synchronous)와 비동기(Asynchronous) 개념 동기는 요청과 그 결과가 동시에 일어난다는 뜻이며, 다시 말하면, 어떤 객체 또는 함수 내부에서 다른 함수를 호출했을 때 이 함수의 결과를 호출한

victorydntmd.tistory.com

https://homoefficio.github.io/2017/02/19/Blocking-NonBlocking-Synchronous-Asynchronous/

 

Blocking-NonBlocking-Synchronous-Asynchronous

꽤 자주 접하는 용어다. 특히나 요즘들어 더 자주 접하게 되는데, 얼추 알고는 있고 알고 있는게 틀린 것도 아니지만, 막상 명확하게 구분해서 설명하라면 또 만만치가 않은.. 그래서 찾아보면

homoefficio.github.io

https://www.youtube.com/watch?v=oEIoqGd-Sns

블로그의 정보

꾸준히 공부하는 개발 노트

HeshAlgo

활동하기