# 동기/비동기 & 블로킹/논블록킹

\


`동기/비동기`

* 요청한 작업에 대해 완료여부를 신경 써서 **작업을 순차적으로 수행할지 여부**에 대한 관점
* 전체적인 작업에 대한 순차적인 흐름 유무
  * 처리해야 할 작업들을 어떠한 '흐름'으로 처리 할 것인가에 대한 관점
* **리턴 값**을 확인유무로 구분

\


`블로킹/논블로킹`

* 현재 작업이 block되는지 여부에 따라 **다른 작업을 수행할 수 있을지**에 대한 관점
* 전체적인 작업의 흐름 자체를 막는지에 대한 여부
  * 처리되어야 하는 (하나의) 작업이, 전체적인 작업 '흐름'을 막느냐 안막느냐에 대한 관점
* **제어권**의 주체를 넘기는지의 여부로 구분

\
\


## 동기(Synchronous) / 비동기(Asynchronous)

![](https://blog.kakaocdn.net/dn/ba8wJ1/btr9wHMcO9E/a1rq2AuO9NKSKxWfvrPL9k/img.jpg)\


### 동기(Synchronous)

* 개념
  * 작업 시간을 맞춰 함께 실행한다
  * 요청한 작업의 작업에 대해 완료 여부를 따져 순차대로 처리하는 것
  * 함수A에서 호출된 함수B의 작업 완료 후 리턴 값을 기다리거나, 완료가 되지 않고 리턴 받더라도 작업 관리 여부를 계속 확인
* 작업 순서
  * 요청한 작업에 대해 순서가 지켜지는 것

\


### 비동기(Asynchronous)

* 개념
  * 요청한 작업의 작업에 대해 완료 여부를 따지지 않고 자신의 다음 작업을 그대로 수행하는 것
    * 동시처리를 통한 시스템 전반적 성능향상
  * 함수 A에서 호출되는 함수 B의 작업 완료에 관계 여부, 리턴 여부를 신경 쓰지 않고 동작
* 작업 순서
  * 요청한 작업에 대해 순서가 지켜지지 않을 수 있는 것

\
\


## Blocking / Non-Blocking

`다른 요청 작업을 처리하기 위해 현재 작업에 대한 block여부를 나타내는 프로세스 실행 방식`

![](https://blog.kakaocdn.net/dn/cUknFY/btr9GgNFkvY/Gk512NEyKX2nkfLlC7w7ok/img.png)

### 블로킹(Blocking)

**개념**

* 자신의 작업을 진행하다가 다른 주체의 작업이 시작되면 다른 작업이 끝날때 까지 기다렸다가 자신의 작업을 실행하는 것
* `호출된 함수(B)`가 자신의 작업이 종료될 때까지 제어권을 갖고 있는 것
  * `호출된 함수(B)`의 작업이 종료될 때까지 `호출하는 함수(A)`는 다른 작업을 진행할 수 없음

\


### 논블로킹(Non-Blocking)

**개념**

* 다른 주체의 작업에 관련 없이 자신의 작업을 하는 것
* 논블로킹은 `호출된 함수(B)`가 자신의 작업이 종료되지 않았더라도 함수의 제어권을 자신을 `호출하는 함수(A)`로 바로 넘겨주는 것

\
\


### 비동기와 논블로킹의 개념 차이

\


> **비동기와 논블로킹**
>
> 비동기는 `출력 순서`와 관련된 개념이고, 논블로킹은 `병령 실행`과 관련된 개념이다.

\


**비동기 논블로킹**

* 개념
  * 다른 작업의 결과를 기다리지 않고(비동기), 병렬적으로 실행되는 방식(논블로킹)
* 구현 기술
  * 비동기 논블로킹 시, 다른 작업의 완료 여부나 결과에 대한 후처리를 위해 이용되는 방식
  * `콜백 함수`
    * 비동기 작업이 완료되면 호출되는 함수의 의미로, 비동기 함수의 매개변수로 함수 객체를 넘기는 기법
    * 콜백 지옥 발생: 콜백 함수가 중첩되어 코드의 깊이가 깊어지는 현상 (코드가 복잡하고 가독성이 떨어지는 문제)
  * `Promise 객체`
    * 비동기 작업의 최종 완료 또는 실패를 나타내는 Array나 Object처럼 독자적인 객체
    * 비동기 작업이 끝날 때까지 결과를 기다리는 것이 아닌, 결과를 제공하겠다는 약속을 반환하는 의미
    * 콜백함수에서 개선된 비동기 논블로킹 처리 제공

> JavaScript의 `setTimeout`를 '비동기 함수'라고 지칭하여 사용하는 것과 같이 비동기와 논블로킹을 혼동하는 경우가 많다. 하지만 비동기는 출력 순서와 관련된 개념이고 논블로킹이 병렬실행과 관련된 개념으로 혼동하지 말자.

\
\


### 제어권

![](https://blog.kakaocdn.net/dn/b3mzcH/btrpJRZSuus/WJLlZj8R2IVqLkO3lwTa60/img.png) ![](https://blog.kakaocdn.net/dn/dobMy7/btrpLub29Xo/TQtuJa2moQ2EHfXmkStTe0/img.png)

* 동기/비동기, 블로킹/논블로킹의 명확한 구분을 위해 나온 개념
* 함수의 코드나 프로세스의 실행 흐름을 제어할 수 있는 권리
* 블로킹과 논블로킹의 구분
  * 호출된 함수(collee)가 호출한 함수(coller)에게 제어권을 바로 주느냐 안주느냐로 구분
  * 제어권이 넘어가면 해당 스레드는 블로킹 됨

\
\


## 동기/비동기 + 블로킹/논블로킹 조합

![](https://blog.kakaocdn.net/dn/1HN9m/btsakdV6qwm/JifIi4frB5yBST4PrCAU1k/img.png)\


### ✔️ Sync Blocking (동기 + 블로킹)

\


**개념**

* 다른 작업이 진행되는 동안 자신의 작업을 처리하지 않고 (`Blocking`), 다른 작업의 완료 여부를 바로 받아 순차적으로 처리하는 (`Sync`) 방식
  * `동기`: 함수 A는 호출한 함수 B의 리턴 값을 필요로 함
  * `블로킹`: 함수 A는 호출한 함수 B에게 제어권을 주고 함수 B에게 제어권을 돌려받을 때까지 실행을 멈추고 기다림

**특징**

* 다른 작업의 결과가 자신의 작업에 영향을 주는 경우 활용
* 코드가 순차적으로 실행 됨
* 일반적으로 작업이 간단하거나 작업량이 적은 경우 사용
* 코드가 순서대로 실행
  * A 실행 후 결과 값 반환 → B 실행 후 결과 값 반환 → C 실행 후 결과 값 반환

**예시**

* 파일을 읽어 내용을 처리하는 로직
  * 파일을 먼저 읽어야 그다음 작업 처리 가능
* C나 JAVA의 코드 실행 후 커맨드에서 입력을 받는 경우
  * 사용자로부터 입력 → 해당 입력값으로 내부 처리 → 결과값 콘솔 출력
  * 제어권을 시스템에서 사용자로 넘김

\
\


### ✔️ Async Non-Blocking (비동기 + 논블로킹)

\


**개념**

* 다른 작업이 진행되는 동안에도 자신의 작업을 처리하고(`Non Blocking`), 다른 작업의 결과를 바로 처리하지 않아 작업 순서가 지켜지지 않는(`Async`)방식
  * `비동기`: 함수 A는 호출한 함수 B의 리턴 값을 신경 쓰지 않으며, 함수 A와 함수 B는 서로 연관성이 없음
  * `논블로킹`: 함수 A는 호출한 함수 B에게 제어권을 주지 않고 계속 실행

**특징**

* 다른 작업의 결과가 자신의 작업에 영향을 주지 않는 경우 활용 가능
* 작업량이 많거나 시간이 오래 걸리는 작업을 처리해야하는 경우 적합

**예시**

* 웹 브라우저의 파일 다운로드
  * 웹 브라우저가 파일 다운로드를 비동기적으로 처리하고 콜백함수를 통해 다운로드 완료되면 알려주는 방식으로 구현
  * 웹 브라우저는 웹 사이트에서 파일 다운로드 시, 파일의 전송이 완료될 때까지 다른 작업을 기다리는 것이 아닌 다른 활동 가능(ex.웹서핑, 다른 창 열기)

\
\


### ✔️ Sync Non-Blocking (동기 + 논블로킹)

\


**개념**

* 다른 작업이 진행되는 동안에도 자신의 작업을 처리하고(`Non Blocking`), 다른 작업의 결과를 바로 처리하여 작업을 순차대로 수행하는(`Sync`) 방식
  * `동기`: 함수 A는 호출한 함수 B의 리턴 값을 중간중간 계속 확인
  * `논블로킹`: 함수 A는 호출한 함수 B에게 제어권을 주지 않고 계속 실행

**특징**

* 호출된 함수에서 작업을 완료하지 않았더라도 제어권을 바로 반납하여 다른 작업을 진행할 수 있도록 함
  * `호출한 함수(A)`는 계속해서 `호출된 함수(B)`의 작업이 끝났는지 확인
  * (B 작업 미완료 시) `호출된 함수(B)` 미완료 회신
    * **이 동안 `호출한 함수(A)`는 다른 작업 수행 가능**
  * `호출된 함수(B)`의 작업이 끝났는지 확인
  * (B 작업 완료 시) `호출된 함수(B)` 결과 값 반환
* 자바는 Sync Non-Blocking코드를 표현하기 적합한 언어
  * 스레드 객체를 만들어 요청 작업을 백그라운드에 돌게 함
  * 메인 메서드에서 while문을 통해 스레드가 모두 처리되었는지 끊임없이 확인하고 처리가 완료되면 다음 메인 작업 수행
*   Java 예시

    ```java
    // Runnable 인터페이스를 구현하는 클래스 정의
    `class MyTask implements Runnable {
        @Override
        public void run() {
            // 비동기로 실행할 작업
            System.out.println("Hello from a thread!");
        }
    }

    public class Main {
        public static void main(String[] args) {
            // Thread 객체 생성
            Thread thread = new Thread(new MyTask());

            // 스레드 실행
            thread.start();

            // Non-Blocking이므로 다른 작업 계속 가능
            System.out.println("Main thread is running...");

            // Sync를 위해 스레드의 작업 완료 여부 확인
            while (thread.isAlive()) {
                System.out.println("Waiting for the thread to finish...");
            }
            System.out.println("Thread finished!");
            
            System.out.println("Run the next tasks");
        }
    }
    ```

    ```
    // 결과

    Main thread is running...
    Waiting for the thread to finish...
    Waiting for the thread to finish...
    Waiting for the thread to finish...
    Hello from a thread!
    Thread finished!
    Run the next tasks
    ```

    * 스레드를 이용해 작업을 병렬적으로 처리하도록 지시
    * Main코드의 while문의 수행으로 요청한 작업의 완료 여부를 계속 확인함
    * 결과적으로 동기 작업으로 작업이 순서대로 수행 됨
* Javascript 경우 Sync Non-Blocking 코드를 구현하기에 지원하는 메서드에 한계가 있어 완벽히 표현할 수 없음
  * `async/await`키워드 이용
    * JavaScript에서 비동기 논블로킹 방식을 동기 논블로킹 방식으로 바꿔줌
    * 하지만 `async/await`는 내부적으로 여전히 비동기 논블로킹 방식으로 동작 함

**예시**

* 게임에서 맵 이동 시
  * 맵 데이터 모두 다운(화면엔 로딩 스크린 뜸)
  * 로딩 스크린은 로딩바가 채워지는 프로그램이 수행하고 있는 것
    * 제어권은 여전히 사용자에게 있어 화면에 로드율이 표시되며 끊임없이 맵 데이터가 어느정도 로드 됐는지 조회
    * 자신의 작업을 계속하고 있지만 다른 작업과의 동기를 위해 계속해서 다른 작업이 끝났는지 조회

\
\


### ✔️ Async Blocking (비동기 + 블로킹)

\


**개념**

* 다른 작업이 진행되는 동안 자신의 작업을 멈추고 기다리는(`Blocking`), 다른 작업의 결과를 바로 처리하지 않아 순서대로 작업을 수행하지 않는(`Async`)방식
  * `비동기`: 함수 A는 호출한 함수 B의 리턴 값을 신경 쓰지 않음
  * `블로킹`: 함수 A는 호출한 함수 B에게 제어권을 주고 함수 B에게 제어권을 돌려받을 때까지 실행을 멈추고 기다림
* `호출된 함수(B)`는 함수의 수행 결과를 콜백함수를 통해 전달, 하지만 `호출된 함수(B)`가 제어권을 가지고 있어 `호출된 함수(B)`의 작업이 완료되기 전까지 `호출한 함수(A)`는 다른 작업 진행 불가

**특징**

* 거의 사용하지 않음
  * 실무에서 잘 마주하기 쉽지 않아 다룰일이 거의 없음
  * Sync Blocking과 성능 차이가 비슷해 사용하는 경우가 거의 없음
* 개발자가 비동기 논블록킹으로 처리하려다가 실수하는 경우, 자신도 모르게 블로킹 작업을 실행하는 의도치 않은 경우 사용 됨
* 따라서 해당 방식을 `안티 패턴(anti-pattern)`이라 치부하기도 함

**예시**

* Node.js + MySQL의 조합
  * Node.js에서 **비동기 방식**으로 DB에 접근
  * MySQL DB에 접근하기 위한 MySQL드라이버는 **블로킹 방식**으로 작동 됨
  * JavaScript는 비동기 방식으로 MySQL에 쿼리를 보냄 (Async)
  * MySQL은 쿼리를 처리하면서 JavaScript에게 제어권을 넘겨주지 않음 (Blocking)
  * JavaScript는 다른 작업을 계속 수행할 수 있지만, MySQL의 결과값을 필요로 하기 때문에 MySQL이 쿼리를 완료할 때까지 기다려야 함
  * 결국 Sync Blocking과 작업 수행에 차이가 없음

> 위 조합은 개발자에게 혼동을 일으키므로 실무에서는 Node.js 서버 프로그래밍 시 async/await로 동기처리를 한다.

\
\


### Ref

[완벽히 이해하는 동기/비동기 & 블로킹/논블로킹](https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-%EB%8F%99%EA%B8%B0%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%B8%94%EB%A1%9C%ED%82%B9%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC)\
[\[컴퓨터 과학 - CS\]동기와 비동기 / 블로킹 논블로킹](https://tang25.tistory.com/entry/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B3%BC%ED%95%99-CS%EB%8F%99%EA%B8%B0%EC%99%80-%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%B8%94%EB%A1%9C%ED%82%B9-%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9)\
[\[network\] 동기vs비동기, 블로킹vs논블로킹의 차이](https://sujinhope.github.io/2021/06/13/Network-%EB%8F%99%EA%B8%B0vs%EB%B9%84%EB%8F%99%EA%B8%B0,-%EB%B8%94%EB%A1%9C%ED%82%B9vs%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9%EC%9D%98-%EC%B0%A8%EC%9D%B4.html)
