출처 - https://github.com/jmxx219/CS-Study (opens in a new tab)
동기/비동기 & 블로킹/논블록킹
동기/비동기
- 요청한 작업에 대해 완료여부를 신경 써서 작업을 순차적으로 수행할지 여부에 대한 관점
- 전체적인 작업에 대한 순차적인 흐름 유무
- 처리해야 할 작업들을 어떠한 '흐름'으로 처리 할 것인가에 대한 관점
- 리턴 값을 확인유무로 구분
블로킹/논블로킹
- 현재 작업이 block되는지 여부에 따라 다른 작업을 수행할 수 있을지에 대한 관점
- 전체적인 작업의 흐름 자체를 막는지에 대한 여부
- 처리되어야 하는 (하나의) 작업이, 전체적인 작업 '흐름'을 막느냐 안막느냐에 대한 관점
- 제어권의 주체를 넘기는지의 여부로 구분
동기(Synchronous) / 비동기(Asynchronous)
동기(Synchronous)
-
개념
- 작업 시간을 맞춰 함께 실행한다
- 요청한 작업의 작업에 대해 완료 여부를 따져 순차대로 처리하는 것
- 함수A에서 호출된 함수B의 작업 완료 후 리턴 값을 기다리거나, 완료가 되지 않고 리턴 받더라도 작업 관리 여부를 계속 확인
-
작업 순서
- 요청한 작업에 대해 순서가 지켜지는 것
비동기(Asynchronous)
-
개념
- 요청한 작업의 작업에 대해 완료 여부를 따지지 않고 자신의 다음 작업을 그대로 수행하는 것
- 동시처리를 통한 시스템 전반적 성능향상
- 함수 A에서 호출되는 함수 B의 작업 완료에 관계 여부, 리턴 여부를 신경 쓰지 않고 동작
- 요청한 작업의 작업에 대해 완료 여부를 따지지 않고 자신의 다음 작업을 그대로 수행하는 것
-
작업 순서
- 요청한 작업에 대해 순서가 지켜지지 않을 수 있는 것
Blocking / Non-Blocking
다른 요청 작업을 처리하기 위해 현재 작업에 대한 block여부를 나타내는 프로세스 실행 방식
블로킹(Blocking)
개념
- 자신의 작업을 진행하다가 다른 주체의 작업이 시작되면 다른 작업이 끝날때 까지 기다렸다가 자신의 작업을 실행하는 것
호출된 함수(B)
가 자신의 작업이 종료될 때까지 제어권을 갖고 있는 것호출된 함수(B)
의 작업이 종료될 때까지호출하는 함수(A)
는 다른 작업을 진행할 수 없음
논블로킹(Non-Blocking)
개념
- 다른 주체의 작업에 관련 없이 자신의 작업을 하는 것
- 논블로킹은
호출된 함수(B)
가 자신의 작업이 종료되지 않았더라도 함수의 제어권을 자신을호출하는 함수(A)
로 바로 넘겨주는 것
비동기와 논블로킹의 개념 차이
비동기와 논블로킹
비동기는
출력 순서
와 관련된 개념이고, 논블로킹은병렬 실행
과 관련된 개념이다.
비동기 논블로킹
- 개념
- 다른 작업의 결과를 기다리지 않고(비동기), 병렬적으로 실행되는 방식(논블로킹)
- 구현 기술
- 비동기 논블로킹 시, 다른 작업의 완료 여부나 결과에 대한 후처리를 위해 이용되는 방식
콜백 함수
- 비동기 작업이 완료되면 호출되는 함수의 의미로, 비동기 함수의 매개변수로 함수 객체를 넘기는 기법
- 콜백 지옥 발생: 콜백 함수가 중첩되어 코드의 깊이가 깊어지는 현상 (코드가 복잡하고 가독성이 떨어지는 문제)
Promise 객체
- 비동기 작업의 최종 완료 또는 실패를 나타내는 Array나 Object처럼 독자적인 객체
- 비동기 작업이 끝날 때까지 결과를 기다리는 것이 아닌, 결과를 제공하겠다는 약속을 반환하는 의미
- 콜백함수에서 개선된 비동기 논블로킹 처리 제공
JavaScript의
setTimeout
를 '비동기 함수'라고 지칭하여 사용하는 것과 같이 비동기와 논블로킹을 혼동하는 경우가 많다. 하지만 비동기는 출력 순서와 관련된 개념이고 논블로킹이 병렬실행과 관련된 개념으로 혼동하지 말자.
제어권
- 동기/비동기, 블로킹/논블로킹의 명확한 구분을 위해 나온 개념
- 함수의 코드나 프로세스의 실행 흐름을 제어할 수 있는 권리
- 블로킹과 논블로킹의 구분
- 호출된 함수(collee)가 호출한 함수(coller)에게 제어권을 바로 주느냐 안주느냐로 구분
- 제어권이 넘어가면 해당 스레드는 블로킹 됨
동기/비동기 + 블로킹/논블로킹 조합
✔️ 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 예시
// 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
완벽히 이해하는 동기/비동기 & 블로킹/논블로킹 (opens in a new tab)
[컴퓨터 과학 - CS]동기와 비동기 / 블로킹 논블로킹 (opens in a new tab)
[network] 동기vs비동기, 블로킹vs논블로킹의 차이 (opens in a new tab)