치춘짱베리굿나이스
블로킹, 논블로킹, 동기, 비동기 본문
이거자꾸헷갈려서적음
이런걸 블로킹이라고 한다
엄청나게 헷갈려서 (…) 엄청나게 많은 블로그 글들을 뒤져가면서 머리속으로 짱구를 요리조리 굴리고 있는데 역시나 엄청나게 헷갈린다
동기 비동기에 관해서도 블로그마다 얘기하는 것이 천차만별이라 누가 맞는지도 잘 모르겠달까,,,
특히 이제 동기 비동기 + 블로킹 논블로킹을 섞어서 동기-블로킹, 비동기-논블로킹 등등이 나오기 시작하면 이제 머리가 터지는거다!!!!!!!!!
동기 / 비동기 (Synchronous / Asynchronous)
여기에 예전에 간략하게 정리해놨던 것이 있다
동기
- A랑 B가 화장실에 가려고 하는데 화장실이 한 칸 뿐이다
- A는 B가 볼일을 다 보고 나서야 화장실에 들어갈 수 있다
- A는 B가 볼일을 다 끝낼 때까지 하염없이 기다리고 있다
- (또는 A가 B에게 주기적으로 노크해서 언제 나올거냐고 물어본다)
- 결국 A는 B의 결과 (볼일을 다 보고 화장실을 나온다) 에 영향을 받는다는 것
함수 A와 B가 있다면,
- A는 B를 호출한다
- A는 B 함수가 반환할 때까지 아무것도 할 수 없으므로 기다리거나, 주기적으로 요청을 보내 할일이 완료되었는지 물어본다
- B 함수에서 반환한 결과값을 A가 처리한다
동기는 할 일 B의 결과값이 다른 할 일 A에도 영향을 준다
앞의 할 일이 뒤의 할 일의 결과값에 영향을 받기 때문에 어느 정도 순차적으로 일이 수행되고, 따라서 실행 순서가 어느 정도 예측된다는 장점이 있다
비동기
- 화장실이 여러 개 있고, A랑 B가 화장실에 가려고 한다
- A는 B가 화장실에 있건 없건 상관없이 화장실에 간다
- A는 B가 화장실에서 나왔건 말건 신경쓰지 않는다
- B는 알아서 볼일을 다 보고 화장실을 나온다
- A는 B의 행위 후 결과에 영향을 받지 않는다
- A가 먼저 볼 일을 다 보고 나올 수도 있고, B가 먼저 나올 수도 있다 (순서가 지켜지지 않을 수 있다)
함수 A와 B가 있다면,
- A는 B를 호출한다
- A는 B 함수가 반환을 하든 말든 신경쓰지 않는다
- B 함수의 후속 동작은 callback에 의해 결정된다
비동기는 할 일 B의 결과값 또는 작업 완료 여부를 할 일 A가 신경쓰지 않는다
한 작업은 다른 비동기 작업이 완료될 때까지 딱히 기다리지도 않고, 다른 할 일을 수행하기도 한다
I/O 작업 및 요청 처리 등 엄청나게 느린 작업을 수행할 때, 결과값을 기다리지 않고 비동기로 처리한다는 것은 곧 동시에 여러 작업을 수행할 수 있다는 것이기 때문에 속도상의 이점이 있다
블로킹 / 논블로킹 (Blocking / Non-Blocking)
블로킹
- A랑 B가 카페에서 떠들다가, B가 화장실에 간다고 한다
- 근데 B가 A의 핸드폰을 들고 가버렸다 (?)
- 제어권 뺏김
- A는 B가 화장실에서 돌아올 때까지 아무것도 못 하고 천장만 바라보고 있어야 한다
- B가 화장실에서 돌아오고 나서야 A는 핸드폰을 볼 수 있게 된다
- 제어권 돌려줌
함수 A와 B가 있다면,
- A는 B를 호출한다
- 이 시점에서, 제어권은 B에게 넘어간다
- A는 B의 작업이 모두 끝날 때까지 대기한다
- B의 작업이 끝났다면, A에게 제어권을 돌려준다
- 이 시점에서, 제어권은 A에게 돌아온다
블로킹 시스템에서는, 하나의 일이 끝날 때까지 다른 일들이 실행될 수 없도록 막는다
논블로킹
- A랑 B가 카페에서 떠들다가, B가 화장실에 간다고 한다
- B는 A에게 자신이 화장실에 가 있는 동안 핸드폰이라도 보고 있으라고 말한다
- 제어권 돌려줌
- B가 화장실에 가 있는 동안, A는 자기 핸드폰을 보면서 시간을 녹일 수 있다
함수 A와 B가 있다면,
- A는 B를 호출한다
- B는 제어권을 다시 A에게 돌려준다
- 이 시점에서, 제어권은 A에게 넘어간다
- A는 B가 할 일을 하던 말던 간에 자신의 할 일을 할 수 있다
논블로킹 시스템에서는, 하나의 일이 끝나지 않았더라도 다른 일을 할 수 있다
두 개를 섞어보자
동기 블로킹 (Sync Blocking)
console.log("A enters the toilet");
console.log("B enters the toilet");
- A는 B의 반환값에 신경을 쓴다 (동기)
- A는 B가 작업을 끝낼 때까지 아무것도 할 수 없다 (블로킹)
- A랑 B가 화장실에 가려고 하는데 화장실이 한 칸 뿐이다
- A는 B가 볼일을 다 보고 나서야 화장실에 들어갈 수 있다
- A는 B의 결과에 영향을 받는다 (동기)
- A는 B가 나올 때까지 하염없이 기다리고 있다
- A는 B가 작업을 끝낼 때까지 아무것도 할 수 없다 (블로킹)
한 쪽 일이 진행되는 동안 다른 쪽 일은 중단되고, 일이 마무리되어 반환값을 받았을 때 비로소 다른 쪽 일을 활성화하는 방식이다
평범하게 우리가 아는 동기적 프로그래밍 방식이다
비동기 논블로킹 (Async Non-Blocking)
setTimeout(() => console.log("A enters the toilet"), 1000);
setTimeout(() => console.log("B enters the toilet"), 1000);
- A는 B의 반환값에 신경을 쓰지 않는다 (비동기)
- A는 B가 작업을 끝낼 때까지 다른 일을 할 수 있다 (논블로킹)
- A랑 B가 화장실에 가려고 하고, 화장실이 여러 칸이다
- A는 B가 볼일을 보든 말든 관심없고, 화장실에 들어갈 수 있다
- A는 B의 결과에 영향을 받지 않는다 (비동기)
- A는 B가 작업을 끝내지 않아도 다른 할 일을 할 수 있다 (논블로킹)
- B가 먼저 나올 수도 있고, A가 먼저 나올 수도 있다
흔히 생각하는 비동기의 수행 방식이다
A와 B는 병렬적으로 동작하고 (혹은 그렇게 보이고) 서로가 서로에게 신경쓰지 않는다
대용량 데이터를 처리하거나 요청 / 응답을 처리하는 등 시간이 오래 걸리는 작업을 할 때 주로 사용되는 방식이다
동기 논블로킹 (Sync Non-Blocking)
- A는 B의 반환값에 신경을 쓴다 (동기)
- A는 B가 작업을 끝낼 때까지 다른 일을 할 수 있다 (논블로킹)
- A랑 B가 화장실에 가려고 하는데 화장실이 한 칸 뿐이다
- A는 B가 볼일을 다 보고 나서야 화장실에 들어갈 수 있다
- A는 B의 결과에 영향을 받는다 (동기)
- A는 B가 나오기 전까지 아무 행동이나 할 수 있다
- A는 B가 작업을 끝내지 않아도 다른 할 일을 할 수 있다 (논블로킹)
- 하지만 A는 B가 나오는 것을 기다려야 하므로, 계속 노크를 반복한다
- A는 B의 작업이 완료되었는지 반복적으로 확인하고, 처리가 완료된 후 다음 작업으로 넘어간다
논블로킹이라곤 하지만 결국 상대방이 일을 다 끝냈는지 여부를 반복적으로 물어봐야 한다는 점에서 A는 제 할 일을 제대로 못 하고 B만을 하염없이 기다린다…
대표적인 예시로 다른 스레드에 할 일을 위임한 뒤, 본 스레드에서는 while 루프를 통해 다른 스레드의 할 일이 끝났는지 확인하는 작업이 있겠다
비동기 블로킹 (Async Blocking)
- A는 B의 반환값에 신경을 쓰지 않는다 (비동기)
- A는 B가 작업을 끝낼 때까지 아무것도 할 수 없다 (블로킹)
- A랑 B가 화장실에 가려고 하고, 화장실이 여러 칸이다
- A는 B가 할일을 다 끝내든 말든 화장실에 들어갈 수 있다
- A는 B의 결과에 영향을 받지 않는다 (비동기)
- 근데 A는 B가 나올 때까지 하염없이 기다리고 있다
- A는 B가 작업을 끝낼 때까지 아무것도 할 수 없다 (블로킹)
블로킹이 걸려 할 일을 제대로 하지 못한다는 점에서 사실상 동기 블로킹 (Sync Blocking) 상황과 별반 차이가 없다
실무에서 자주 일어나지도 않을 뿐더러 대부분이 의도치 않게 발생한다고 한다
참고 자료
https://velog.io/@maketheworldwise/SyncAsync-BlockingNon-Blocking-무슨-차이일까
https://inpa.tistory.com/entry/👩💻-동기비동기-블로킹논블로킹-개념-정리#sync_blocking_조합
'이론적인 부분들 > 기타' 카테고리의 다른 글
도메인 주도 설계와 아키텍처 (0) | 2023.11.10 |
---|---|
디자인 패턴이란 (0) | 2022.09.24 |