동기 프로그래밍은 쉽게 설명하자면 순차적인 프로그래밍을 이야기한다. 예를들어 파스타를 만들어보자.
- 물을 끓인다. (3분)
- 면을 넣고 10분동안 기다린다. (13분)
- 면을 체에 건진다. (13.5분)
- 마늘과 버섯을 알맞은 크기로 자른다. (15분)
- 팬에 올리브유를 두르고 마늘과 버섯을 넣고 볶는다. (18분)
- 면수와 치킨스톡을 넣고 기름과 섞은 뒤 면을 넣고 30초정도 볶아준다. (20분)
1번이 끝나면 2번을 시작, 2번이 끝나면 3번을 시작해서 6번까지 순차적으로 실행하는 방식이 바로 동기 프로그래밍이다.
비동기 프로그래밍은 동기의 반대인 순차적이지 않은것이다. 좀 더 정확히는 정해진 순서대로 일을 맡기고 기다리는 방식이다. 방금의 파스타 만들기를 비동기로 바꾸어보자.
- 물을 끓인다.
- 물이 끓는동안 마늘과 버섯을 자른다.
- 물이 끓으면 면을 넣고 10분동안 기다린다. (3분)
- 10분 기다리는 동안 팬에 올리브유를 두르고 마늘과 버섯을 볶는다.
- 면수와 치킨스톡을 넣고 기름과 섞는다.
- 면을 건진 뒤 만든 소스에 넣고 30초정도 볶아준다. (13.5분)
동기의 상황과 순서는 조금 다르다. 하지만 본질은 같다. 큰 차이점은 시간이다. 그 이유는 전자는 물이 끓고 면을 삶는동안 기다렸고, 후자는 다른 작업을 했기 때문이다.
전자는 물이 끓는동안 나는 할 일이 없다. 하지만 후자는 물을 끓이고 면은 삶아지게 일을 맡겨놓고 나는 다른 일을 처리한다. 다른일을 하다가 물이 끓으면 면을 넣고 다른일을 한다. 면이 다 삶아지면 건지고 또 다른일을 한다.
쓰레드에 대한 이야기를 해보자. 이제는 내가 푸드코트에서 일을 하게 되었다고 생각하자. 저 파스타를 10명이 1그릇씩 주문한다고 하자.
멀티쓰레드는 주문을 받는 곳이 여러개다. 마치 대형마트의 계산대처럼 말이다. Sync와 Async 두가지 경우가 있을 것이다.
만일 계산대가 4개라고 하자.
- 1, 2, 3, 4번 손님을 각각 1, 2, 3, 4번 계산대에 보내 음식을 주문한다.
- 손님은 계산대에서 음식이 다 완료될때까지 기다리고 음식이 나오면 자리로 간다.
- 음식이 완료되어 계산대가 비게되면 5번 손님을 빈 계산대로 보낸다.
- 1, 2, 3, 4번 손님을 각각 1, 2, 3, 4번 계산대에 보내 음식을 주문한다
- 주문이 완료되면 자리로 가 번호표를 받고 음식을 기다린다.
- 계산이 완료되어 계산대가 비게되면 5번 손님을 빈 계산대로 보낸다.
- 음식이 나오면 번호를 알려주고 음식을 받는다.
싱글쓰레드는 주문을 받는 곳이 한개다. 계산대가 하나인 것이다. 마찬가지로 Sync와 Async의 두가지 경우가 있을 것이다.
- 1번 손님을 계산대에 보내 음식을 주문한다.
- 손님은 계산대에서 음식이 다 완료될때까지 기다리고 음식이 나오면 자리로 간다.
- 음식이 완료되어 계산대가 비게되면 2번 손님을 빈 계산대로 보낸다.
- 1번 손님을 계산대에 보내 음식을 주문한다
- 주문이 완료되면 자리로 가 번호표를 받고 음식을 기다린다.
- 계산이 완료되어 계산대가 비게되면 2번 손님을 빈 계산대로 보낸다.
- 음식이 나오면 번호를 알려주고 음식을 받는다.
정리하자면 멀티쓰레드는 10가지 업무를 나누어 처리하고 싱글쓰레드는 10가지 업무를 차례대로 처리한다.
멀티쓰레드
- 여러가지 업무를 동시에 처리할 수 있다. 따라서 빠른 업무가 가능하고 기다림이 적다.
- 계산대에 모두 손님을 보내고 남은 사람들이 한줄서기처럼 기다린다면, 빈 계산대를 찾아 보내주는 관리자가 필요하다.
- 공유 자원이 있다면 관리가 필요하다. 이를 block / lock이라고 한다.
싱글쓰레드
- 순차적이라 복잡하지 않고 block과 관리비용이 없다.
- 다만 한번에 하나밖에 못한다.
자바스크립트는 싱글쓰레드에 Async 방식을 사용한다.
작업공간인 쓰레드는 하나지만 Async를 사용하여 시간을 공유한다. 면이 삶아지는 동안 소스를 만드는 것처럼 시간을 공유하는 것이다.
기본적으로 자바스크립트에서는 event를 이용해 Async를 구현한다. 화면을 클릭하거나 스크롤, 사용자의 입력, 화면의 사이즈 등 event가 발생하면 callback을 실행한다.
또한 AJAX와 같은 기술로 외부와 통신한다던가 하는 작업을 비동기로 처리한다.
그래서 유명한 다음 그림이 나온다.
이를 더 자세히 보려면 이제 이벤트루프에 대한 개념이 필요하다. 이는 eventLoop 에서 설명한다.