많은 종류의 소프트웨어에서 동기 처리 방식이 Blocking이고, 비동기 처리 방식이 Non-Blocking이여서 동기와 Blocking, 비동기와 Non-block를 비슷한 개념으로 오해할 수 있다. 단지 일련의 작업들에 대해 순차적으로 하나씩 처리하고 완료하는 방식은 매 작업의 수행마다 Blocking하는 게 작업의 순서를 보장하기 쉬우며, 작업의 완료 상태를 신경쓰지 않고 여러 작업들을 번갈아 처리하는 구조에서는 한 작업을 수행하면서 Non-Blocking으로 다른 작업을 받아와서 처리하는 구조가 효율적이기 때문에 동기와 Block, 비동기와 Non-block이 자주 쓰이는 것이다.
그렇기 때문에 같은 개념으로 혼동하기 쉽지만, 이 두 가지 개념은 서로 다른 곳에 초점을 맞춘 개념이다.
- Block/Non-block은 프로세스의 유휴 상태(제어권)에 대한 개념
- 동기/비동기는 프로세스의 작업 순서 보장(먼저 요청한 작업의 응답 확인 후 다른 요청)에 대한 개념
💻 Block, Non-block
호출된 대상(함수, App)이 제어권을 바로 반환(return)하느냐 갖고 있느냐가 관심사다.
Block
호출된 대상이 자신의 작업을 모두 마칠 때까지 제어권을 계속 갖고 있어서 호출한 대상은 아무 일도 못하고 대기
Non-block
호출된 대상이 자신의 작업을 마치지 않았어도 제어권을 바로 반환하여 호출한 대상은 다른 일을 진행 가능
💻 동기(Synchronous), 비동기(Asynchronous)
호출한 대상 A이 호출된 대상 B의 작업의 완료 상태를 확인하는지에 따라 작업 순서를 보장하는가
Syn은 together이란 뜻이고, chrono는 time이다. 따라서 Synchronous는 '함께 시간을 맞춘다' 라는 뜻으로 해석된다. 프로그래밍에서의 동기는 현재 작업의 처리가 끝나는 시간에 맞춰 다음 작업을 요청하는 것을 말한다. 반면 Asynchronous는 부정형이 되어 '시간을 맞추지 않는다' 라고 해석할 수 있다.
동기(Synchronous)
- 현재 작업의 응답이 끝나는 시간과 맞춰 동시에 다음 작업을 요청한다.
- 함수를 호출한 곳에서 호출된 함수가 결과를 반환할 때까지 대기한다.
- 작업 완료 여부를 계속해서 확인한다.
비동기(Asynchronous)
- 현재 작업의 응답이 끝나지 않은 상태에서 다음 작업을 요청한다.
- 함수를 호출한 곳에서 완료 여부를 신경쓰지 않고, 호출된 곳에서 작업이 끝나면 callback으로 결과를 전달
- callback 함수는 다른 함수의 인자로 들어간 함수로서 특정 시점에 실행되게 되는 함수
- 작업 완료 여부를 확인하지 않는다.
콜백 함수는 비동기 프로그래밍을 실현하는 기본적인 방법으로, 특정 함수의 작업이 진행되는 동안 다른 작업을 하다가 특정 함수의 작업이 끝나면 콜백함수를 실행해 호출한 곳으로 결과를 전달한다.
비동기 처리가 왜 필요한가?
결과를 즉시 받을 필요가 없거나, 지연하여 처리해야 하는 작업을 위해 활용된다.
비동기처리 방식이 항상 동기처리 방식에 비해서 좋은 것만은 아니다. 비동기처리 방식이 동기처리 방식보다 좋아지려면 수행할 작업이 단순 연산 중심이 아니라 중간마다 지연되는 형태의 작업이어야 한다. 대표적으로 데이터 등을 인터넷에 다운로드 받고 이를 처리하는 함수들은 먼저 데이터를 다운로드 받는 데 시간이 소요되는데 이런 작업은 비동기처리 방식을 사용하는 것이 좋다. 이와 달리 이미 데이터는 준비되어 있고 단순히 데이터에 대한 단순 연산으로 구성된 경우라면 비동기처리 방식으로 이를 처리한다고 해도 얻을 수 있는 이점이 없다. 또한, 비동기 방식으로 태스크들을 잘 처리하려면 스케줄러가 필요하다는 점도 고려해야 한다.
💻 Block/Non-block vs 동기/비동기
ex. 손님이 카페 직원에게 커피를 주문하는 상황
Block: 손님은 직원에게 커피를 주문하면, 직원은 손님에게 커피가 완성될 때까지 그 자리에서 기다리라고 제어
Non-Block: 손님은 직원에게 커피를 주문하면, 직원은 손님에게 다른 일을 하고 있으라고 제어권 반환
동기: 손님은 직원에게 커피를 주문하면, 손님은 커피가 완료되었는지 계속 물어보면서 순서대로 대기
비동기: 직원에게 커피를 주문하면, 손님은 커피 완료 여부를 신경쓰지 않고 진동벨이 울리면 전달 받음
1) 동기/Blocking
함수 A는 함수 B에게 리턴값을 받아야 하므로, 요청을 완료했는지 계속 물어본다. (동기)
제어권을 함수 B에게 넘겨주고, 함수 B가 실행을 완료하여 리턴값과 제어권을 돌려줄 때까지 기다린다. (Blocking)
☕
즉 진동벨(callback함수)이 없어서 커피가 완성되었는지 계속 물어보면서(동기), 카운터 앞에서 기다린다.
ex. 파이썬의 input 함수 실행 후 커맨드에서 입력값을 받는 상황
제어권이 시스템(함수 A)에서 사용자로 넘어가, 함수 A는 리턴값이 필요하기 떄문에 사용자가 입력할 때까지 기다린다.
2) 동기/Non-blocking
A 함수는 B 함수를 호출한다.
A 함수는 B 함수에게 제어권을 주지 않고, 자신의 다른 일을 계속 수행한다. (Non-blocking)
그런데 A 함수는 B 함수의 리턴값이 필요하기 때문에, 중간 중간 B 함수에게 요청을 완료했는지 물어본다. (동기)
☕
즉 진동벨(callback함수)이 없어서 커피가 완성되었는지 계속 물어보지만(동기), 다른 일을 하고 있을 수 있다.
ex. 게임에서 맵을 이동할 때 맵 데이터를 계속 물어보면서 제어권은 여전히 나한테 있어 화면에 로드율이 표시된다.
3) 비동기/Non-Blocking
A 함수는 B 함수를 호출한다.
A 함수는 B 함수에게 제어권을 주지 않고, 자신의 다른 일을 계속 수행한다. (논블로킹)
A 함수는 B 함수의 리턴값에 신경 쓰지 않고, 콜백 함수를 보낸다. (비동기)
B 함수는 자신의 작업이 끝나면 A 함수가 준 콜백 함수를 실행해 응답한다.
☕
즉 진동벨(callback함수)이 있어서 커피 완성 여부를 신경쓰지 않으며(비동기), 다른 일을 계속 진행한다.
ex. AJAX 요청, JS 비동기 콜백
프론트엔드 단에서 서버로 API 요청을 보내고, 응답을 기다리지 않고 바로 자신의 다음 일을 계속 실행한다.
4) 비동기/Blocking
A 함수는 B 함수의 리턴값에 신경 쓰지 않고, 콜백 함수를 보낸다. (비동기)
B 함수의 작업에 관심이 없음에도 불구하고, A 함수는 B 함수에게 제어권을 넘긴다. (블로킹)
따라서, A 함수는 자신과 관련 없는 B 함수의 작업이 끝날 때까지 기다려야 한다.
☕
즉 진동벨(callback함수)이 있어서 커피 완성 여부를 신경쓰지 않아도 되는데, 카운터 앞에서 기다린다. 그래서 진동벨이 없어서 카운터 앞에서 기다리는 동기/blocking과 성능의 차이가 비슷하기 때문에 사용하는 경우는 거의 없다.
참고:
https://ko.wikipedia.org/wiki/%EC%BD%9C%EB%B0%B1
https://www.programmersought.com/article/20384435112/
https://inpa.tistory.com/category/KNOWLEDGE/CS%20%EC%A7%80%EC%8B%9D
'컴퓨터 과학(CS) > 운영체제' 카테고리의 다른 글
현대의 운영체제: 인터럽트 기반 시스템, 컴퓨터 버스 (0) | 2022.01.16 |
---|---|
운영체제의 개념과 역할, 구조 (0) | 2022.01.14 |
컴퓨터 동작 원리: BIOS와 부트 로더 (0) | 2022.01.13 |
컴퓨터 구조와 메모리 계층 구조(Memory hierarchy) (0) | 2022.01.12 |
댓글