프로그램을 실행하면 프로세스가 생기잖아요?
프로세스는 기본적으로 한 개의 실행 스레드를 가지고 시작되고요 이 스레드가 우리가 작성한 main 함수를 실행시켜줍니다.
그런데 우리는 프로세스 내에서 2개 이상의 일을 동시에 진행해야 될 때가 있어요
사용자로부터 입력을 받아 처리하는 작업, 그리고 입력에 따라 상태를 갱신하거나 화면을 그리는 작업을 예로 들어볼게요
이 작업들을 한 개의 스레드에서만 처리하려면
1. 입력을 받아서 처리하기
2. 입력에 따라 상태를 갱신하거나 화면을 그리기
위와 같이 차례대로 작업을 수행하는 것을 반복해야 되겠죠?
하지만 이렇게 되면 입력을 받는 동안에는 상태를 갱신하거나 화면을 그리지 못하고 반대로 상태를 갱신하거나 화면을 그리는 동안에는 입력을 받지 못하게 됩니다.
각 작업의 시간이 매우 짧으면 작업이 거의 동시에 일어나는 것처럼 느끼기 떄문에 사실 크게 문제는 없어요. (이것을 동시성이라고 합니다)
그런데 만약 입력을 scanf로 받아야된다고 하면 어떨까요?
입력을 받는 동안 상태를 갱신하거나 화면을 그리지 못하겠죠?
이를 해결하기 위해 스레드라는 것을 추가로 만들면 해당 스레드에서 다른 작업을 동시에 수행할 수 있어요. (이것을 병렬성이라고 합니다)
이 외에도 멀티 프로세서/스레드에서 성능 향상을 목적으로 한다거나 여러 이유가 있지만 위와 같은 이유로 스레드라는 개념이 필요하구요
비동기 함수라는 것도 일반적으로 방금 말한 스레드를 사용하여 구현되어 있습니다.
우리가 아는 일반적인 함수는 호출 후 값이 반환될때까지 기다려야하는 동기 함수이고요
비동기 함수는 호출 시 별도의 스레드가 생성되어 현재 스레드와 별개로 동시적으로 작업을 수행합니다.
(인터럽트 등을 활용하여 스레드 없이 동시 작업을 흉내내는 경우도 있는데요 이것은 엄밀하게 말하면 비동기 함수가 아닙니다)
그리고 일반적으로 비동기 함수는 작업이 끝났을 때 수행할 코드를 함수 형태로 전달해주는 경우가 많고요
작업이 끝났다는 이벤트에 의해 호출되기 떄문에 callback 함수라고 이름이 지어졌습니다.
?
쓰레드 왜쓰냐? CPU 활용도 높이려고요. 이거 하나면 된다 뭔 글에 이렇게 기노 - dc App
위 예시처럼 CPU 활용도만으로는 설명할 수 없는 부분도 존재합니다.
스레드를 만든다고 무조건 병렬성을 보장하진 않지 않나요? 커널 스레드가 아닌이상 유저스레드로 만들면 그냥 한 cpu에서 가상화해서 동작하는거 아니었뜸?
(인터럽트 등을 활용하여 스레드 없이 동시 작업을 흉내내는 경우도 있는데요 이것은 엄밀하게 말하면 비동기 함수가 아닙니다) 이것도 궁금하네요. 그럼 뭐라고 부르나요? 비동기랑 스레드는 상관없는거 아니었나영
하이퍼스레드 기능을 사용하면 그렇고요, 물리 코어/스레드가 여러 개인 경우 실제로 별개로 병렬적으로 돌아갑니다
엄밀하게 말하면 비동기 함수가 아니라는 말은 추가 설명이 필요한데요 caller에서 실행 결과를 기다리지 않는 것처럼 보여도 실제로는 인터럽트의 도움을 받든 어떠한 방법을 쓰든 cpu의 pc 자체를 다른 곳으로 넘겨서 실행 흐름을 조작하면 인터럽트가 발생하기 전까지는 결국 제어권을 넘겨받을 수 없으므로 본질적으로는 완전히 비동기가 아니라는 얘기입니다.