print(1+1) // 1 출력
time.sleep(1) // 1초 쉬고
print(2+2) // 4 출력
- 파이썬은 내부에서 코드를 읽을 때 위부터 차례대로 읽기 시작한다. 이 코드에 경우 1이 출력되고, 1초 쉬고 4가 출력된다.
- 이처럼 위부터 아래로 한번에 코드를 한줄씩 처리하는 것을 동기식 처리(synchronous) 라고 한다. 거의 모든 프로그래밍 언어가 이 방식을 차용하고 있다.
- 파이썬처럼 자바스크립트를 실행하는 웹브라우저 또한 Stack이라는 연산 공간에서 한번에 한 줄씩 코드를 실행한다.
//브라우저 콘솔
console.log(1+1);
console.log(2+2);
setTimeout(function(){}, 1000)
console.log(3+3);
/*출력결과
2
4
6(1초 쉬지않고 바로 출력)
*/
- 그런데 브라우저 콘솔에서 해당 코드를 실행할 경우 순차적으로 코드를 실행함에도 불구하고, 3번째 코드가 실행되지 않아 6이 1초 뒤에 출력되야함에도 바로 출력된다.
- 이는 JS 만이 갖는 타언어와의 다른점으로, 이렇게 오래걸리는 작업을 실행시 해당 작업을 후순위로 밀어 다른 작업부터 처리하게 하는 방식이다.
- 이러한 처리방식을 전문용어로 비동기식 처리(asynchronous)라고 한다.
- 우리가 사용하는 웹브라우저는 C++로 만들어졌는데, 브라우저는 실행해야할 자바스크립트 코드를 발견하면 stack에 넣어 돌린다.
- stack은 코드를 해석해서 맨 윗줄부터 하나하나 실행시키는 공간이다. 브라우저 내부에 한개만 존재하고, heap 이라는 공간에 저장된 변수들을 가져다 사용한다.
- stack은 한번에 한 코드만 실행할 수 있어 single thread language 라고 불린다.
- 즉 이러한 웹브라우저의 비동기적 처리는 JS가 아닌 웹 브라우저의 특성에 기반한 것이다.
- 셋타임아웃, Ajax 요청 코드 등 처리시간이 오래걸리는 코드들은 Stack에 쌓아놓지 않고, 대기실같은 공간(Web api)에 잠깐 보류해놨다가 완료되는 시점에 Stack으로 보낸다.
- Stack은 항상 바쁘기때문에, Stack이 텅 빈 시점에만 보류된 코드를 불러온다.
- 실행준비가 되면 이런 코드들을 Queue라는 대기장소에 집어넣고, 들어온 순서대로 처리한다. (권총에 탄창을 넣고- 공이를 당기고- 방아쇠를 당겨 발사하는 과정을 떠올려보자.)
console.log(1+1); //1번
setTimeout(function(){console.log(2+2)}, 1000)//2번
console.log(2+2);//3번
console.log(3+3);//3번
/*출력결과
2
4
6
*/
- 이에 따라 위의 코드를 해석하면,
- 일단 세 코드를 모두 queue에 불러서 대기열을 만든다.
- 1번 코드를 Stack으로 보내 바로 실행시키고, 2번 코드는 처리시간이 오래 걸리므로 처리를 보류하고, queue의 4번 코드의 후순위로 대기한다.
- 3,4번 코드를 처리한 후, 후순위에 있는 2번 코드가 실행된다.
라는 뜻이다.
for (let i = 0; i < 1e10; i++) {
i++;
}
- Stack과 queue의 이런 특성때문에, 이렇게 100억번 돌리는 단일 반복문을 돌리면 시간이 오래걸릴 수 밖에 없다. 10초 동안 연산을 한다고 하면 10초 동안 사용자는 아무것도 할 수가 없는 것이다.
- 셋타임아웃을 이용해서 0초마다 0~1억 반복, 1억~2억 반복, 2억~3억 반복... 이렇게 코드를 실행하면 쾌적하게 작업을 수행할 수 있다.
- 0.4초마다 Queue로 보내기 때문에 사이사이의 이벤트리스너같은 코드를 실행가능하기 때문이다. (setTimeout 타이머를 0초로 설정해도 4ms로 동작하기 때문에 설정 가능한 최소 시간은 4ms이다.)
//main.js
var myWorker = new Worker('worker.js');
w.onmessage = function(e){
console.log(e.data);// 이러면 1이 나온다.
}
//worker.js 파일
var i = 0 ;
postMessage(i + 1);//postMessage라는 특별한 함수가 있다.
- Web worker는 스크립트가 웹페이지 이용해 지장을 주지 않도록 별도의 작업쓰레드를 만들어 병렬처리하도록 돕는다.
- 사용자의 이용환경을 개선하기 위해 멀티쓰레드 작업이 필요할 경우 사용하면 된다. 더 자세한 이용환경은 https://developer.mozilla.org/ko/docs/Web/API/Web_Workers_API/Using_web_workers
에서 확인해보도록 하자.