동기(Synchronous)와 비동기(Asynchronous)
동기/비동기는 주로 어플리케이션에서 다루는 개념으로. 다음 작업이 요청되는 시간
과 관련이 있는 개념이다. 각각 앞글자를 따서 동기는 sync, 비동기는 async로 지칭하는 경우가 많다. 이들은 처리해야 하는 작업들을 어떠한 흐름
으로 처리할 것인가에 대한 관점으로 이해하면 된다.
동기
- 요청(Request) 이후 응답(Response)을 받아야 다음 동작이 이루어지는 방식이다.
- 즉, 현재 작업의 응답과 동시에 다음 작업의 요청이 일어난다.
- 어떤 작업이 수행되고 있는 동안 다른 작업은 정지된다.
- 작업의 완료 여부를 해당 함수를 호출한 쪽에서 확인한다.
- CPU의 자원 사용 측면에서 다소 비효율적이다.
비동기
- 요청 이후 응답을 받지 않아도 다음 동작을 수행하는 방식이다.
- 어떤 작업이 수행되는 동안에도 다른 작업을 수행할 수 있다.
- 요청 시 해당 로직의 처리 결과를 알려주는 callback 함수를 함께 사용한다.
- 콜백 함수는 처리를 마친 시스템이 호출하는 것으로, 콜백 함수가 호출되면 해당 로직을 요청했던 함수는 그 결과를 확인한다.
- CPU의 자원을 더 효율적으로 사용할 수 있다.
패스트푸트 매장에서 어떤 손님이 음식을 주문했다고 가정하자. 음식이 조리되는 동안 손님이 계속해서 "음식 다 됐나요?"를 물어보고 그때마다 직원은 "아직이요.", "준비 중입니다."와 같이 응답하다가 조리가 다 되었을 때 손님이 "음식 다 됐어요?"라고 물어보면 그때 "네, 다 됐습니다."라고 답하는 경우, 이는 동기식이다(이때, 직원이 먼저 "음식 다 됐습니다"라고 말하는 경우는 없다).
반대로 음식을 주문한 손님은 가만히 기다리고 주문이 다 되었을 때 직원이 "손님, 주문한 음식 나왔습니다."라고 말해야 비로소 손님이 음식을 가져간다면 이는 비동기식이라고 할 수 있다.
블로킹(Blocking)과 논블로킹(Non-blocking)
블로킹과 논블로킹은 주로 멀티 스레딩이나 I/O 등에서 사용되는 개념으로 함수의 리턴 시점과 제어권
에 관한 개념이다. 즉, 호출된 함수가 제어권을 점유하는가
를 기준으로 구분한다고 이해할 수 있다.
블로킹
- 호출된 함수가 제어권 가져가는 방식
- 호출된 함수가 작업을 완료할 때까지 다른 함수는 작업을 수행할 수 없다.
- 즉, 작업이 완료된 후에야 새로운 작업을 수행할 수 있다.
- 호출된 함수)의 실행이 끝나면 해당 함수는 결과와 함께 제어권을 호출한 함수에 돌려준다.
- CPU의 자원 낭비가 심한 방식
논블로킹
- 호출한 함수가 제어권을 계속 가지고 있는 방식
- 제어권이 호출한 함수에 있으므로 호출된 함수의 작업 완료 여부와 무관하게 새로운 작업을 수행할 수 있다.
- CPU의 자원은 효율적으로 사용하나, 요청이 동시에 대량으로 발생할 경우 CPU의 부담이 증가할 수 있음
앞서 식당의 예에서, 음식을 주문한 손님이 아무것도 하지 않고 가만히 앉아 기다린다면 블로킹 방식, 손님이 뉴스를 보거나 매장을 둘러보거나 아니면 직원에게 음식의 영양성분을 물어보는 등 다른 일을 하면서 기다린다면 논블로킹 방식이라고 할 수 있을 것이다.
조합
Sync-Blocking
- 함수 A가 함수 B를 실행함과 동시에 제어권을 넘겨주고 작업이 완료될 때까지 기다린다(블로킹).
- 함수 A는 함수 B의 리턴값이 돌아올 때까지 작업 완료 여부를 확인한다(동기)
Sync-Nonblocking
- 함수 A가 함수 B를 실행하면서 제어권을 넘겨주지 않고 자신의 작업을 계속 수행한다(논블로킹).
- 함수 A는 함수 B의 리턴값이 돌아올 때까지 작업 완료 여부를 확인한다(동기)
Async-Nonblocking
- 함수 A가 함수 B를 실행하면서 제어권을 넘겨주지 않고 자신의 작업을 계속 수행한다(논블로킹).
- 함수 B를 호출할 때 콜백 함수를 함께 전달하고, 작업이 완료되면 콜백 함수를 통해 완료 여부를 함수 A에 알리도록 한다. 그리고 그동안 함수 A는 함수 B의 작업 완료 여부에 대해서는 신경 쓰지 않는다(비동기).
Async-Blocking
- 함수 A가 함수 B를 실행함과 동시에 제어권을 넘겨주고 작업이 완료될 때까지 기다린다(블로킹).
- 함수 B를 호출할 때 콜백 함수를 함께 전달하여 작업 완료 여부를 함수 A에 알리도록 한다.
※ Async-Blocking의 경우 전체 모습을 보아도 알 수 있듯 이런 식으로 동작할 이유가 거의 없는 방식이다. 따라서 이렇게 조합되어 사용되는 경우는 거의 없고, 마주할 일이 거의 없는 방식이다.
참고 자료