Sync/Async와 Blocking/Non-Blocking
1. 동기(Sync)
일반적으로 동기
라고 함은, 먼저 실행된 함수의 동작이 완료될 때까지 대기하는 것을 말하며, 이는 마치 놀이기구를 운영하는 방식과 비슷합니다. 예를 들어, 바이킹의 정원이 20명이고, 한 번 동작하는데 15분이 소요된다고 가정해봅시다. 바이킹이 진자운동을 시작하면, 다음 차례를 기다리고 있는 대기자는 15분 후에 탑승할 수 있습니다. 이를 다르게 말하자면, 바이킹 탑승 및 하차는 동기적으로 관리된다고 할 수 있습니다.
2. 비동기(Async)
일반적으로 비동기
라고 함은, 함수의 실행 순서와 관계 없이 결과가 먼저 나오는 것을 말합니다. 이는 마치 카페와 비슷한데, 예를 들어, 카페에는 20곳의 좌석이 있다고 가정해봅시다. 대부분의 카페에서는 선착순으로 줄을 서서 결재 후 음료를 받을 수 있습니다. 이들은 음료를 다 마셔도 카페에서 바로 나오지 않고, 수다, 공부 등 개인적인 이유에 따라 카페에 머물러 있곤 합니다. 이를 다르게 말하자면, 사람들마다 카페에서 나오는 순서가 서로 다르며, 입장 및 퇴장이 비동기적으로 수행된다고 할 수 있습니다.
3. Blocking
일반적으로 Blocking
(또는, Blocking Model
)은 코드의 실행이 끝나기 전까지 실행 제어권을 다음 코드로 넘기지 않는 방식을 말합니다. 즉, 실행 제어권을 받지 못한 후속 코드는 계속 대기하는 상태가 됩니다. 예를 들어, 실행 중인 코드는 위의 바이킹 예시에서 탑승자에 해당하고, 대기 중인 후속 코드는 줄서 있는 대기자에 해당합니다.
4. Non-Blocking
일반적으로 Non-Blocking
(또는, Non-Block Model
)은 코드의 실행이 끝나지 않아도 다음 코드로 실행 제어권을 넘기는 방식을 말합니다. 예를 들어, 실행 중인 코드는 손님으로부터 음료 결재를 받는 카페에 해당하고, 후속 코드는 결재를 완료한 손님에 해당한다고 할 수 있습니다. 결재를 완료한 손님은 음료를 받은 후 카페 좌석에 대한 결정권을 얻게 됩니다. 달리 말하자면, 카페는 좌석에 대한 제어권을 손님들에게 넘겨준 상태라고 할 수 있습니다.
5. 연관성
코드의 제어권을 후속 코드로 넘겨주면(Non-Blocking) 비동기 처리가 가능하지만, 비동기 처리가 가능한 환경일지라도 후속 코드로 제어권을 넘기지 않으면(Blocking) 비동기 처리가 불가능합니다. Javascript의 기본 모델은 Non-Blocking이며, 각 명령은 순서대로 처리될 수 있는 환경이지만, Non-Blocking이 아닌 모든 함수는 비동기적으로 실행됩니다. 이를 대표하는 API로는 아래 코드에서 사용한 setTimeout
이 있습니다.
const callback = () => console.log('out');
setTimeout(callback, 2000);
console.log('come');
console.log('in');
위 코드를 실행하면 다음과 같이 출력되는 것을 확인할 수 있으며, 그 결과를 통해 Javascript는 Non-Blocking으로 동작한다는 사실을 확인할 수 있습니다.
come
in
out
만약, Javascript가 Non-Blocking이 아니었다면, Python3의 sleep(2)
와 같이 동작하여, 2초 후에 아래와 같이 출력될 것입니다.
out
in
come