보통 블로킹&동기, 논블로킹&비동기가 쌍이다. 사실 블로킹과 동기, 논블로킹과 비동기는 비슷한 소리를 하고 있다. 단지 관점이 다르다. 블로킹/논블로킹은 제어권에 대해, 동기/비동기는 호출된 함수의 리턴에 주목한다.
Blocking & Nonblocking
제어권이란 자신의 코드를 실행할 권리 정도로 보면 된다.
Blocking
Blocking은 A함수가 B함수를 호출할 때 제어권도 넘긴다. 제어권을 잃은 A함수는 자신의 코드를 실행하지 못하고, 반대로 B함수는 호출됨과 동시에 자신의 함수를 실행하게 된다. B함수가 신나게 자신의 코드를 다 실행하고 나면 리턴값과 함께 제어권을 다시 A함수로 넘겨준다. 그러면 그제서야 제어권이 생긴 A함수는 자신의 나머지 코드를 실행하게 된다.
이걸 함수 스택관점에서 보면 A함수 때문에 다른 함수들은 하염없이 기다리게 된다. 이것도 블로킹이 일어났다고 표현한다.
Nonblocking
Nonblocking은 A함수가 B함수를 호출하여도 제어권을 넘겨주지 않는다. 그래서 A함수는 B함수의 호출과 상관없이 자신의 코드를 계속 실행시킬 수 있다. 그러다 언젠가 B함수의 연산이 끝나 리턴값이 들어오면 그 값을 받는 것이다.
어라? B함수는 제어권이 없는데 어떻게 자신의 코드를 실행해서 리턴값을 반환하느냐? 묻는다면 사실 그건 나도 모르겠다,,,, 몰라,,, (웹 기준) 아마 서버에 뭔가 요청하는 작업을 B함수로 호출하면 서버에서 동작한 뒤 응답을 전달하는 것으로 아는데 이거에 해당하는 내용인지 정확하지 않음
Synchronous & Asynchronous
Synchronous란 무엇인가? 동기(同期), 같은 시기, 동시 발생... 즉 Request와 Respones가 같이 오는 것이다.
동기는 태스크A가 끝이 나야 태스크B를 시작할 수 있다. 이렇게 두 태스크의 끝과 시작이 동시에 일어나기 때문에 동기라는 이름이 붙은 것이다.
그에 비해 비동기는 태스크끼리의 끝과 시작이 반드시 동시에 일어나지 않는다. 태스크A를 실행하는 중간에 대충 B, C를 시작(호출)해두고 끝난 놈의 값을 회수하는 식인 것이다.
웹에 이를 적용해보면, 동기는 클라이언트(브라우저)가 무엇을 요청하면 아무고토 못하고 멍청하게 기다리다가 데이터를 받는다. 그러나 비동기는 브라우저가 무언가를 요청해두고 다른 일을 할 수 있다.
동기 ) 첫 손님이 커피를 주문하면 그 커피가 완료될 때까지 그 손님은 아무것도 할 수 없다. 첫 손님의 커피가 만들어져 반환됨과 동시에 두번째 손님의 주문이 들어온다. 그리고 손님 하나의 주문이 들어간 상태에서는 뒤의 다른 손님들까지 아무것도 할 수 없다. 즉 블로킹이 일어난다.
비동기 ) 첫 손님이 커피를 주문한 뒤 테이블로가 자신의 다른 일을 할 수 있다. 동시에 다른 손님들도 자신의 주문을 바로 넣을 수 있다. 커피가 완성되어 반환되면 손님은 자신의 커피를 회수하고 다시 자신의 일을 이어간다.
참고
https://www.youtube.com/watch?v=8aGhZQkoFbQ&ab_channel=JSConf