FrontEnd/JavaScript

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

뽀루피 2024. 7. 18. 17:12

 

동기와 비동기, 블로킹과 논블로킹은 프로그램의 실행 흐름과 리소스 관리에 중요한 역할을 한다. 

 

 

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

 

 

동기(Synchronous)와 비동기(Asynchronous)에 대해 이해하기 쉬운 이미지를 가져와봤다. 

동기순차적으로 실행하며 작업이 완료할 때까지 대기해야 한다.

비동기병렬적으로 실행하며 다른 작업의 완료를 대기하지 않아도 된다. 하지만 결과의 순서를 예측하기 어렵다.

그래서 끝났을 때의 결과 이벤트 처리를 위해 콜백 함수promise 등을 준비해놓는다.

 

 

둘을 비교한 표를 보면 둘의 특징이 명확하다.

특성 동기 (Synchronous) 비동기 (Asynchronous)
작업 처리 방식 순차적, 한 번에 하나의 작업 병렬적, 여러 작업 동시 처리
흐름 제어 작업 완료까지 대기 작업 완료를 기다리지 않음
결과 처리 즉시 처리 콜백, 이벤트, 프로미스 등으로 처리
코드 실행 순서 예측 가능 예측 어려움
자원 활용 대기 시간 동안 리소스 유휴 효율적인 리소스 활용
구현 복잡도 상대적으로 간단 상대적으로 복잡
적합한 상황 간단한 작업, 순차적 처리 필요 I/O 작업, 네트워크 요청 등 시간이 걸리는 작업
성능 단일 작업에 효율적 다중 작업에 효율적
에러 처리 직관적, try-catch 사용 복잡, 에러 콜백 또는 프로미스 체인 사용

 

 

 

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

 

블로킹(Blocking)과 논블로킹(Non-Blocking)은 단어에서 알 수 있듯 다른 요청의 작업을 처리하기 위해 현재 작업을 block 하는지 안하는지 여부로 나타내는 프로세스 실행 방식이다.

이를 좀 더 컴퓨터 과학적으로 설명할 때 등장하는 용어가 '제어권'이다. 제어권은 쉽게 말해 함수의 코드나 프로세스의 실행 흐름을 제어할 수 있는 권리이다. 이 '제어권'을 호출된 함수(callee)가 호출한 함수(caller)에게 제어권을 넘기느냐 유지하느냐로 블로킹, 논블로킹으로 나뉘는 것이다.

 

 

블로킹

블로킹

 

1. A함수가 B 함수를 호출하면 B함수에게 제어권을 넘긴다.

2. 제어권을 넘겨받은 B 함수는 실행되고 A 함수는 제어권이 없기 때문에 함수 실행을 멈춘다.

3. B 함수가 완료되면 자신을 호출한 A에게 제어권을 돌려준다.

 

 

논블로킹

논블로킹

 

1. A 함수가 B 함수를 호출하면 A 함수는 제어권을 그대로 가지고 있고, B함수는 실행만 시킨다.

2. A 함수는 제어권을 가지고 있기 때문에 B 함수를 호출하고 나서도 A 함수를 계속해서 실행한다.

 

 

 

둘을 비교한 표를 통해 특징을 보자.

특성 블로킹 (Blocking) 논블로킹 (Non-Blocking)
제어권 호출된 함수가 제어권을 가짐 호출한 함수가 제어권을 유지
대기 상태 호출된 함수 완료까지 대기 호출 후 즉시 반환, 대기 없음
자원 활용 대기 중 리소스 유휴 상태 효율적인 리소스 활용
실행 흐름 순차적 실행 병렬적 실행 가능
응답성 상대적으로 낮음 상대적으로 높음
구현 복잡도 상대적으로 간단 상대적으로 복잡
적합한 상황 간단한 로직, 빠른 작업 I/O 작업, 긴 실행 시간 작업
에러 처리 직관적 복잡할 수 있음
성능 단일 작업에 효율적 다중 작업에 효율적

 

 

 

동기와 비동기, 블로킹과 논블로킹 이 둘은 비슷한 듯 보이지만 관심사가 다르다.

동기와 비동기는 호출되는 함수의 작업 완료 여부를 따지는가? 에 관심이 있고,

블로킹과 논블로킹은 호출한 함수, 호출되는 함수 중에 제어권이 누구한테 있는가? 에 관심이 있다.

 

 이러한 관심사는 둘의 조합으로 명확하게 알 수 있다.

 

 

동기 - 블로킹

 

우리가 주로 사용하는 동기 함수의 형태이다.

동기: 작업 완료한 결과 즉, 리턴값을 필요로 한다.

블로킹: A 함수가 B 함수에 제어권을 넘겨주고 완료되면 다시 제어권을 돌려받는다.

 

 

동기 - 논블로킹

 

논블로킹 : A 함수는 B 함수를 호출할 때 제어권을 넘기지 않는다.

동기 : 하지만 A 함수는 B 함수의 리턴값이 필요하다. 따라서 계속 B 함수에 완료 여부를 확인해야 한다.

 

 

비동기 - 블로킹

 

비동기: A 함수는 B 함수의 리턴값에 신경쓰지 않는다. 대신 콜백함수를 넘긴다.

블로킹: A 함수는 B 함수에 제어권을 넘기면서 B 함수의 작업이 끝날 때까지 기다린다.

자바스크립트에서 사용하는 async/await가 이 예시에 해당한다.

 

비동기 - 논블로킹

 

논블로킹: A 함수는 B 함수 호출 시 제어권을 주지 않고, 실행만 시킨다. 물론 제어권이 A 함수에 있으므로 실행된다.

동기: B 함수를 호출할 때 콜백함수를 넘긴다. B함수는 자신의 작업이 끝나면 A 함수가 준 콜백함수를 실행한다.

 

 

참고 : https://velog.io/@nittre/%EB%B8%94%EB%A1%9C%ED%82%B9-Vs.-%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9-%EB%8F%99%EA%B8%B0-Vs.-%EB%B9%84%EB%8F%99%EA%B8%B0