동기와 비동기, 블로킹과 논블로킹을 처음 접할 때는 서로가 비슷하다고 생각한다.
결론부터 말하면 동기와 비동기, 블로킹과 논블로킹은 바라보는 관점 자체가 다르다.
동기와 비동기가 바라보는 관점은 결과값을 기다리는 지 여부이다.
- 결과값의 기다림 : 함수 호출자와 피호출자가 있을 때 함수 호출자가 피호출자가 주는 결과를 전달 받기 전까지 기다리는 것을 의미한다.
블로킹과 논블로킹의 관점은 제어권의 여부이다.
- 제어권 : 코드를 실행하는 권리와 비슷하다. 제어권을 가진 함수는 자신의 코드를 실행할 수 있다.
동기 (Synchronous)
동기의 키포인트는 결과값을 기다린다는 것이다.
따라서, 호출자는 피호출자가 로직을 처리하고 결과값을 전달해줄 때 까지 기다린다.
비동기 (Asynchronous)
비동기의 키포인트는 결과값을 기다리지 않는다는 것이다. 즉, 함수 호출자는 피호출자의 결과값 전달해주는 것에 대해 관심이 없는 것이다.
따라서, 호출자는 피호출자에게 함수를 호출하면서 콜백함수를 전달한다. 이 콜백 함수는 피호출자가 로직을 모두 처리하면 실행된다.
블로킹 (Blocking)
블로킹의 키포인트는 제어권을 주는 것이다.
함수 호출자는 피호출자를 호출함과 동시에 제어권을 넘겨준다.
함수를 호출한 호출자는 제어권을 돌려받기 전까지 자신의 코드를 실행하지 못하고 대기한다.
피호출자가 자신의 로직을 모두 수행하면 다시 호출자에게 제어권을 넘겨주고, 호출자는 제어권을 돌려받았으므로 다시 자신의 로직을 실행한다.
논블로킹 (Non-Blocking)
논블로킹의 키포인트는 제어권을 주지 않는 것이다.
함수 호출자는 피호출자를 호출하지만 제어권을 넘겨주지 않는다.
따라서, 호출자는 자신이 제어권을 갖고 있기 때문에 자신의 코드를 계속해서 실행한다.
동기와 비동기, 블로킹과 논블로킹
동기와 비동기, 블로킹과 논블로킹은 관점의 차이가 있지만, 함께 사용된다.
동기/블로킹 (Synchronous + Blocking)
동기 + 블로킹은 호출자가 피호출자를 호출할 때 제어권을 피호출자에게 넘겨주고, 피호출자가 결과를 전달해 줄 때까지 대기한다.
- 함수 A가 함수 B를 호출하면서 제어권을 넘겨준다.
- 제어권이 함수 B에게 있기 때문에 함수 A는 자신의 로직을 처리하지 못한다. 즉 블로킹 상태이다.
- 함수 B는 자신의 로직을 처리한 후 제어권과 함께 결과값을 함수 A에게 전달한다.
- 함수 A는 제어권을 돌려받았으므로 결과값을 가지고 다음 로직을 처리한다. 즉 동기 상태이다.
Java는 대표적인 동기 + 블로킹 방식이다.
동기 / 논블로킹 (Synchronous + Non-Blocking)
동기 + 논 블로킹은 호출자가 피호출자를 호출한 후 제어권을 돌려받는다. 하지만 결과값을 기다리기 때문에 피호출자에게 지속적으로 결과가 나왔는지 요청한다.
피호출자 결과를 전달해주면 자신의 로직을 처리한다.
- 함수 A는 함수 B를 호출하고, 제어권을 돌려받는다.
- 함수 B는 자신의 로직을 처리한다. 함수 A는 자신이 제어권을 가지고 있으므로 자신의 함수를 실행할 수 있다. 즉, 논블로킹 상태이다.
- 함수 A는 함수 B의 결과값을 전달받아야할 때 까지 기다려야한다.
- 따라서, 함수 A는 지속적으로 함수 B에게 결과가 나왔는지 요청하고, 결과값이 나오면 전달받은 결과값을 가지고 로직을 처리한다. 즉 동기 상태이다.
대표적인 동기 + 논블로킹 방식은 게임에서 맵을 이동할 때 로딩화면이 있다.
맵을 이동할 때 지속적으로 맵이 로딩이 되었는지 피호출자에게 물어보고 (자신이 계속 물어볼 수 있으므로 제어권은 자신에게 있다. 논블로킹) 맵이 모두 로딩(결과값의 전달, 동기)되면 맵을 사용자에게 보여준다.
비동기 / 블로킹 (Asynchronous + Blocking)
비동기 + 블로킹은 호출자가 피호출자를 호출할 때 제어권을 전달한다. 그리고 결과값을 기다릴 필요가 없기 때문에 콜백함수를 전달한다.
- 함수 A는 함수 B를 호출할 때 제어권을 전달한다.
- 함수 A는 자신에게 제어권이 없기 때문에 자신의 이후 로직을 처리하지 못한다. 즉 블로킹 상태이다.
- 함수 B는 자신의 로직을 처리한 후 함수 A로부터 전달받은 콜백함수를 실행한다. 즉 비동기 상태이다.
- 함수 B는 자신의 모든 로직을 처리했으므로 함수 A에게 제어권을 전달한다.
- 함수 A는 자신의 로직을 처리한다.
비동기 + 블로킹 방식은 함수 A가 자신과 관련없는 함수 B의 로직 처리를 기다린다.
이런 경우는 개발자의 실수로 인해 설정이 잘못되듯 의도치 않게 실행되는 경우가 다반사이다.
성능 차이는 동기 + 블로킹 방식과 비슷하다.
비동기 / 논블로킹 (Asynchronous + Non-Blocking)
비동기 + 논블로킹은 호출자가 피호출자를 호출한 후 제어권을 돌려받는다. 또한, 결과값을 기다릴 필요가 없기 때문에 피호출자를 호출할 때 콜백함수를 함께 전달한다.
- 함수 A는 함수 B를 호출하고 제어권을 돌려받는다.
- 함수 B는 자신의 로직을 처리하고 함수 A는 자신이 제어권을 가지므로 자신의 함수를 실행한다. 즉 논블로킹 상태이다.
- 함수 A는 함수 B의 결과를 기다릴 필요가 없다.
- 따라서, 함수 A는 함수 B의 결과를 몰라도 되고, 함수 B는 함수 A로부터 전달받은 콜백함수를 실행한다. 즉 비동기 상태이다.
Javascript의 AJax 요청은 대표적인 비동기 + 논블로킹 방식이다.
Ajax 요청은 서버로 데이터를 호출 후 자신의 로직을 처리하고, 서버가 결과값을 전달해주면 콜백함수를 진행한다 .
📄 References
블로킹 Vs. 논블로킹, 동기 Vs. 비동기 : https://velog.io/@nittre/블로킹-Vs.-논블로킹-동기-Vs.-비동기
[10분 테코톡] 🐰 멍토의 Blocking vs Non-Blocking, Sync vs Async : https://www.youtube.com/watch?v=oEIoqGd-Sns
'Computer Science > OS' 카테고리의 다른 글
뮤텍스(Mutex), 세마포어(Semaphore) (0) | 2022.07.03 |
---|---|
프로세스 동기화 (Process Synchonization) (0) | 2022.07.03 |
프로세스, 스레드 (0) | 2022.06.07 |