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

이진경·2023년 3월 28일

✅ Blocking vs Non-Blocking (제어권)

둘의 큰 차이는 다른 주체가 작업을할때 본인한테 제어권 이 있는가 없는가의 차이이다.

👉 제어권이란? 함수의 코드를 실행할 권리이다. 제어권을 가진 함수는 자신의 코드를 끝까지 실행한 후 자신을 호출한 함수한테 돌려준다.

👉 결과값을 기다린다? A함수에서 B함수를 호출했을 때, A함수가 B함수의 결과값을 기다리느냐의 여부이다.

✍️ Blocking이란?

(파일기준)바깥에서 어떤걸 가져와야 됨 / disk io가 일어나는 경우 / 네트워크 io가 일어나는 경우(통신) ( img파일 src로 읽어올때)

1️⃣ 자신의 작업을 진행하다가 2️⃣ 다른 주체의 작업이 시작(제어권 전달)되면 다른 작업이 3️⃣ 끝날때까지 기다렸다가(제어권 반환) 4️⃣ 자신의 작업을 시작.

✍️ Non-Blocking이란?

메모리 / 그냥 계산만

1️⃣ 자신의 작업을 진행하다가 2️⃣ 다른 주체의 작업의 시작된다해도 3️⃣ 제어권은 그대로 자신이 가지고 있는다.

  • 제어권은 A함수가 그대로 가진 상태로 B함수는 호출만 시킨다.

✅ 동기 vs 비동기 (시간)

둘의 큰 차이는 호출되는 ☝️ 함수의 작업 완료 여부를 신경쓰는가? 그리고 함수 실행과 리턴같은 ✌️ 순차적인 흐름을 따르는가의 관심사이다

✍️ 동기란?

  • 작업을 동시에 수행하거나, 동시에 끝나거나, 끝나는 동시에 시작한다.
  • 호출하는 A함수가 호출되는 B함수의 작업 완료 후 리턴을 기다리거나 바로 리턴 받더라도 미완료 상태라면 작업 완료 여부를 계속 확인하며 신경쓴다.

✍️ 비동기란?

  • 시작, 종료가 일치하지 않고, 끝나는 동시에 시작을 하지 않는다.
  • 호출하는 A함수가 B함수를 호출할때 콜백함수를 함께 전달해서 B함수의 작업이 완료되면 함께 보낸 콜백 함수를 실행한다.
  • A함수는 B함수를 호출한 후에 B함수의 작업 완료 여부를 신경쓰지 않는다.

🔥 동기 / 비동기 + 블로킹 / 논블로킹의 조합

동기 / 비동기와 블로킹 / 논블로킹을 같은 개념이라고 오해를 많이 하지만, 전혀 다른 곳에 초점을 맞춘 개념이다. 서로 직접적인 연관은 없고, 조합되어 사용될 뿐이다.

✍️ 동기 + 블로킹

이 조합이 사용되는 대표적인 언어는 JAVA이다.

:: 실생활에서의 예 (밥 짓기)

💡 너무 배가 고파서 밥을 먹으려고 했는데 밥이 없넹? 😱 (무조건 흰쌀밥에 먹어야 됨)

나 = A함수 / 밥솥 = B함수

  1. 나는 쌀을 씻어서 밥솥에 넣고 실행버튼을 누른다.
    • A함수 작동하다가 B함수를 실행시키면서 제어권을 넘겨줌.
  2. 밥솥은 뚝딱뚝딱 열심히 밥을 만든다 🍚 → 그동안 나는 밥도 못 먹고 하염없이 밥이 완성되기만을 기다린다.
    • B함수가 작동할때까지 A함수는 제어권을 넘겨줬기때문에 실행을 멈춤
  3. 밥이 완성 됐다!! 밥솥은 밥을 나한테 제공해줬고, 나는 이제 밥을 먹을 수 있다!
    • B함수가 리턴값과 제어권을 돌려줌
  4. 밥을 먹는다.
    • B함수의 리턴값을 가지고 남은 코드를 실행한다.

✍️ 동기 + 논블로킹 (크롤러와 백엔드 서버 / 크롤러 도는 동안 결과 상관 안씀)

1️⃣ 논블로킹이기때문에 호출되는 함수는 제어권을 바로 호출하는 함수에게 다시 넘겨준다. (코드 실행 완료 여부 상관없이) 또 2️⃣ 동기 방식이기때문에 호출하는 함수쪽에서 완료 여부를 신경 쓰고, 완료됐는지 확인하는 요청이 필요하다 그리고 또 동기방식이기때문에 작업의 순서는 지켜진다.

이 조합이 사용되는 예는 크롤러와 백엔드 서버이다.

👩🏻‍💻 유저가 서비스 연동하기 버튼 클릭하면 크롤러가 실행되고 백엔드는 유저한테 알림을 전송한다.

👻 크롤러는 크롤링을 실행하고, 🧟‍♀️ 백엔드 서버는 크롤링의 완료여부와 상관없이 연동이 완료되면 이메일을 보내주겠다는 알림을 전송한다.

🧟‍♀️ 백엔드 서버는 크롤링이 완료되었는지 계속 확인을 하고, 완료됐다면 결과값을 프론트에 보내준다.

✍️ 비동기 + 블로킹 (많지 않음)

async + await

1️⃣ 비동기 방식이기때문에 호출하는 함수는 작업 완료 여부를 신경쓰지 않는다.

블로킹으로 인해 B함수가 호출되는 순간 B함수에게 제어권이 넘어가고, A함수는 제어권을 다시 받을때까지 다른 작업을 할 수 없다.

  • 실수로 사용하는경우

    해당 방식은 넌블록킹으로 하려다가 실수하는 경우에 발생하거나, 우리도 모르게 의도치 않게 사용된다.(개발자가 비동기, 논블로킹 작업을 실행하였지만 자기도 모르게 블로킹 작업을 실행했을 때)
    (Node.js + MySQL의 조합이 대표적인데, Node.js에서 비동기(async)적으로 DB 작업을 수행하더라도 블로킹 방식으로 작동하는 MySQL 드라이버를 거치게 된다.)

✍️ 비동기 + 논블로킹

async

가장 일반적으로 이야기되는 비동기 처리 방식이다.

1️⃣ 비동기 방식이기때문에 함수를 호출한 곳에서 결과를 처리하지 않고 다른 곳에서 결과는 처리한다 (callback)

그리고 2️⃣ 논블로킹이기 때문에 함수가 호출되고 제어권은 바로 호출한 함수로 다시 넘어오게 되어 다음 코드를 실행한다.

profile
멋찐 프론트엔드 개발자가 되자!

0개의 댓글