본문으로 바로가기

동기/비동기 vs 블로킹/논블로킹

category etc 2021. 2. 11. 22:02

동기/비동기 vs 블로킹/논블로킹

Redis를 세션 스토리지로 적용하는 과정에서 Java의 대표적인 Redis client 인 Jedis와 Lettuce 중 Netty 기반의 Redis 클라이언트인 Lettuce를 사용하기로 결정했다. Netty는 비동기 이벤트 기반의 고성능 네트워크 프레임워크인데, 여기서 나온 비동기의 개념을 확실히 짚고 넘어가고자 정리하기로 했다.

동기/비동기 vs 블로킹/논블로킹

동기와 비동기 또는 블로킹과 논블로킹 중 하나를 떠올리면 자연스럽게 나머지 단어들도 떠오르게 된다. 그 이유는 둘의 개념적인 의미가 비슷하기 때문이다.

하지만 실제로 두 개념은 서로 연관관계가 없는 별개의 개념으로 기억해야 한다.

동기/비동기

먼저 동기와 비동기에 대해 알아보자.

  1. 동기(synchronous)

    synchronous를 한국말로 해석하면 동시에 일어나는 이라는 뜻이다. 말 그대로 요청과 결과가 동시에 일어난다는 뜻이다. 우리가 어떤 작업에 대한 요청을 하면, 그 요청에 대한 응답시간이 얼마가 걸리던지 요청에 대한 결과를 받을때 까지 기다려야 한다.

     

두 개의 쓰레드가 존재한다. 만약 Thread1에서 처리하려고 했던 일을 Thread2에게 보낸다면 아래와 같은 그림이 형성될 것이다.

 

위 그림을 통해서 알 수 있는 점은 Thread21이라는 작업을 처리하는 동안 Thread1은 아무 작업도 처리하지 못하고 대기하고 있다는 점이다. Thread21이라는 작업을 끝내야 Thread1에서 2라는 작업을 처리할 수 있는 것이다.

 

  1. 비동기(Asynchronous )

    Asynchronous 는 한국말로 동시에 일어나지 않는 이라는 뜻이다. 요청과 결과가 동시에 일어나지 않는다. 즉, 우리가 어떤 작업에 대한 요청을 하면 , 그 요청에 대한 결과가 반환되지 않았더라도 이어서 바로 다른 작업을 처리할 수 있게 된다.

     

     

마찬가지로 두 개의 쓰레드가 존재한다. Thread1 에서 처리하려고 했던 작업을 Thread2로 보낸다면 비동기의 경우 아래와 같은 그림이 형성된다.

 

Thread2의 작업이 완료되지 않아도 Thread1에서 바로 다음 작업을 처리할 수 있다.


블로킹/논블로킹

다음으로 블로킹과 논블로킹을 알아보자.

  1. 블로킹(blocking)

    어떤 작업을 처리하는 메소드(호출한 메소드)실행 과정에서 다른 메소드를 호출(호출된 메소드)한다고 생각해보자. 호출된 메소드의 작업이 끝날때 까지 호출한 메소드에게 제어권을 넘겨주지 않고 대기하게 만든다면 블로킹이다.

     

메소드1의 작업을 처리하다가 메소드2가 호출되면, 메소드2의 작업이 완료될때까지(값을 리턴받을때 까지) 메소드1은 대기하게 된다.

 

  1. 논블로킹(non-blocking)

    논블로킹은 블로킹과 반대로, 어떤 메소드 실행 과정에서 다른 메소드를 호출한다고 해도, 호출된 메소드의 완료 여부와 상관 없이 바로 제어권을 다시 넘겨받아 호출한 메소드가 계속해서 다른 작업을 처리할 수 있도록 한다.

     


사실 여기까지 봤을때는 (동기/비동기)와 (블로킹/논블로킹)의 차이가 와닿지 않는다.

의미적으로만 보면 동기블로킹은 막거나 기다리거나 하는 등 뭔가 비효율적인 동작을 하는 느낌인 반면에, 비동기논블로킹은 막지도 않고 작업이 완료 되던지 말던지 신경쓰지 않고 추가적으로 일을 처리하는 등 효율적으로 동작하는 느낌이 나기 때문에다.

 

비동기 + 논블로킹 예시

이해를 돕기 위해 실생활에서 (동기/비동기) 와 (블로킹/논블로킹)이 적용된 예시를 찾던 도중 좋은 포스팅 을 발견했다.

  • 개발 팀장이 사원1에게 업무A를 , 사원2에게 업무B를 , 사원3에게 업무C를 지시하였다.(비동기적 작업 지시)

  • 각 사원들에게 지시를 끝낸 후 개발팀장은 다른 업무를 처리하러 간다.

  • 사원들은 각자 본인이 맡은 작업을 끝내는대로 개발 팀장에게 보고한다.(논블로킹 방식의 작업 처리)

여기서 비동기는 개발 팀장이 사원1에게 지시한 일이 끝나지 않았음에도 사원2와 사원3에게 업무를 지시한 경우가 비동기적 작업 지시라고 볼 수 있다.

또한 개발 팀장의 작업 흐름의 주된 내용은 업무 지시다. 지시한 업무가 완료되지 않았지만 개발 팀장은 다른 일을 처리하러 갔다. 그리고 사원들은 일이 끝나는대로 개발 팀장에게 보고한다. 즉, 업무 지시에 대한 리턴 값은 사원들의 보고인데, 사원들의 보고 여부와 상관 없이 다른 일을 처리하러 가기 때문에 논블로킹이다.

 

정리

(동기/비동기)와 (블로킹/논블로킹)은 관심사가 다르다는 점을 염두에 두고 생각해야 한다.

동기(Synchronous)비동기(Asynchronous)작업의 완료에 초점을 두고 있다.

  • 하나의 쓰레드가 작업이 완료될때 까지 기다렸다가 다른 쓰레드에서 작업을 시작하면 동기
  • 하나의 쓰레드가 작업이 완료 되던지 말던지 신경쓰지 않고 다른 쓰레드에서 작업을 할 수 있드면 비동기

반면에 블로킹(Blocking)논블로킹(NonBlocking)은 호출되는 함수의 리턴 시점에 초점을 두고 있다.

  • 호출된 함수가 바로 리턴하지 않고, 제어권을 가지고 있으면서 해당 함수가 종료될 때 제어권을 넘긴다면 블로킹
  • 호출된 함수가 완료되지 않아도 제어권을 바로 호출한 함수에게 넘긴다면 논블로킹

참고자료

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