동기/비동기 방식은 작업이 다른 작업의 실행에 의존을 하는지, 영향을 미치는지로 구분한다.
동기(Synchronous)는 한 작업이 다른 작업에 의존하고 있어 다른 작업이 끝나야 작업을 시작할 수 있다.
비동기(Asynchronous)는 작업이 다른 작업에 영향을 받지 않아 외부 요인과 상관 없이 작업을 시작할 수 있다.
# 동기 방식 프로그래밍
|<----A----><-B-><-----C-----><-------------D------------->
# 비동기 방식 프로그래밍
|<----A---->
|<-B->
|<-----C----->
|<-------------D------------->
동기 방식 프로그래밍을 할 때는 작업끼리 영향을 미치기 때문에 위 예시에서 A작업이 종료되어야 B 작업, C 작업, D 작업이 순서대로 실행될 수 있다. 하지만 비동기 방식 프로그래밍을 할 때는 작업간에 영향을 미치지 않기 때문에 다른 작업에 상관없이 차례가 오면 작업을 시작하고 끝난다.
동기 방식은 다른 작업의 결과물이 필요한 경우에 사용되는데 문제는 다른 작업이 언제 종료될지 알 수 없다는 것이다. 선행 되어야하는 작업이 끝날 때까지 기다려야 하고 전체 작업의 종료시간도 늦어진다는 단점이 있다. 하지만 작업 순서를 조작할 필요가 없어 설계하기에 편리하다.
비동기 방식은 각 작업이 다른 작업과는 관계없이 작업을 시작하고 종료하기 때문에 전체적인 작업 시간이 단축돼 자원을 효율적으로 사용할 수 있다는 장점이 있다. 단점은
블로킹은 '제어권'이라는 개념과 관련이 있는데, 제어권이란 자신의 작업을 실행할 수 있는 권한이다.
블로킹(Blocking)은 함수 내부에서 다른 함수를 호출할 때 그 함수에게 자신의 제어권을 넘겨준다.
넌블로킹(Non-Blocking)은 함수 내부에서 다른 함수를 호출할 때 그 함수에게 제어권을 넘겨주지 않고 계속 가지고 있는 것을 의미한다. 그래서 다른 함수와 관련 없이 함수 나머지 부분을 계속 작업할 수 있다.
# Blocking
|<----A-----↓ ↑----------->
| <-----B----->
# Non-Blocking
|<----------|-----A----------------->
| <-----B----->
Blocking 방식을 보면 A 작업에서 B 작업을 호출할 때 제어권도 넘겨줘(↓ 기호) A 작업은 잠시 중단되고 제어권을 되찾기를 기다리고 있다. B의 작업이 종료되고 A가 제어권을 회수했을 때(↑) 다시 작업이 재개되는 모습을 볼 수 있다. Non Blocking 방식을 보면 A 작업에서 B 작업을 호출( | )해도 제어권은 여전히 A에게 있기 때문에 A, B작업은 각자 작업을 수행한다.
동기와 블로킹 개념은 막상 보면 비슷해 보이지만 관점에 따라 약간은 다르다. 동기 / 비동기는 다른 작업에 영향을 받는지 여부에 따라 구분하고, 블로킹은 다른 함수에 제어권을 넘겨주는지 여부에 따라 구분한다. 이 개념들을 믹스해 4가지 경우를 도출할 수 있다.
|<----A-----↓ ↑----------->
| <-----B----->
|<----A----- ❓ ❓ ❓ ❓ ❓ ----------->
| <------B------>
|<----A-----↓ ↑----------->
| <-----B----->
|<----------|-----A----------------->
| <-----B----->