동기 vs 비동기
동기, 비동기의 원래 의미는 통신에서 상대방의 일정 신호에 의해서 다음 동작이 이루어지면 동기, 상대방의 상태와 상관없이 일방적으로 동작하면 비동기이다.
즉, 상대방이 받을 준비 됬다는 신호를 받아서 한 byte를 보내고 수신측에서 한 byte를 받은 후 또 보내도 된다는 신호를 보내고 이 신호 확인 후에 보내는게 동기식이다. 이에 반하여 비동기에서는 일단 한번 전송이 시작되면 쭉 보낸다.
이와 비슷한 개념으로 일반 software에서 동기식이라 함은
어떤 루틴이 완전히 끝내고 제어를 반납하면 동기식
동작이 안 끝났어도 일단 제어권을 반납한 후 자기 할일을 계속하면 비동기 이다.
이게 무슨말이냐 하면 예를들어 siren 소리를 낼때
play_sound(“siren_wav”,”동기”); a=b+c; …
이러면 사이렌 소리가 다 끝난 후 a=b+c가 실행되고
play_sound(“siren_wav”,”비동기”); a=b+c; …
이러면 a=b+c 이하 프로그램을 계속 수행하면서 siren소리가 난다.
file조작도 마찬가지이다.
즉 file 조작이 완전히 끝난 후 다음 동작이 이루어지는 것이 동기,
다음 코드를 진행하면서 file조작을 하면 비동기이다.
이러한 비동기식은 DOS같은 단일 운영체제에서는 근본적으로 불가능하고 windows같은 multitask같은 환경에서만 가능하다.
file조작에서는 cpu속도와 hard 등의 저장매체와 엄청난 속도 차이가 있기 때문에 비동기로 처리해도 대용량data를 read/write할 때는 일시적으로 system이 버벅이게 된다.
일반적으로 windows같은 multi task환경에서는 동기식 처리는 시스템 효율 저하가 일어난다. 동기식에서는 어떤일을 처리할 동안 다른 프로그램은 정지하게 되므로 실제 cpu가 느려지는 것은 아니지만 시스템 전체적으로는 효율이 저하된다고 할 수 있다는 것이다.
호출스택(Call stack) 의 차이
동기식 호출스택은 위의 설명과 같이 차례대로 쌓이게 된다.
예를들어
funcA();
funcB();
funcC();
이런식으로 존재하면 funcA가 모두 실행되고 나서 funcB가 실행되고 이런식으로 차례대로 진행되기때문에 입력순서대로 쌓이게된다.
하지만 비동기식에서는
setTimeout(callback);
funcA()
funcB()
여기서 setTimeout은 대표적인 비동기함수이다.
setTimeout의 콜백함수는 즉시 실행되지 않고 지정 대기시간만큼 기다렸다가 ‘tick’ 이벤트가 발생하면 이벤트 큐로 이동한 후 CallStack이 비어졌을때 Call Stack으로 이동되어 실행된다.