Weekly Flutter

dart의 EventLoop는 어떻게 동작할까?

taby 2023. 3. 8. 10:54

아시다시피, 다트는 싱글스레드 언어입니다.

같은 싱글스레드 언어인 js에서는 eventLoop를 중요시 여기며 많이 들어보았는데,

Dart의 eventLoop는 어떻게 동작하는지 궁금하여 찾아보게 되었습니다.

 

 

dart는 isolate라는 독립적인 코드 실행 공간을 가지고 있는데요.

flutter앱을 실행시키는 순간 isolate라고 불리는 프로세스가 생성된다고 합니다. 이 isolate는 내부적으로 하나의 eventLoop를 가지고 있고 두개의 관련 Queue를 갖습니다.

 

dart의 isolate

isolate는 별도의 메모리 공간에서 실행되는 독립적인 작업자로 스레드와 유사하지만 몇가지 다른 점을 갖습니다.

isolate는 dart vm의 별도 인스턴스입니다.

각 isolate에 자체 메모리 힙, 프로그램 카운터및 스택이 있으며 다른 isolate와 독립적으로 자체 dart코드를 실행합니다.

서로의 메모리를 방해하지 않고 각각 병렬로 실행될 있습니다. 

스레드의 특징인 메모리의 공유가 없습니다.dart의 설계에서 isolate간의 메모리 공유는 error-prone 이기 때문에 제외되었다고 합니다.

만약 한 프로그램에서 다른 isolate를 생성할 시 두 isolate는 메시지를 통해 통신합니다.

dart에서 isolate(Parallelism)이 필요할 때,

대부분의 경우 우리는 future-async를 통해서 비동기적 코드를 실행하는데, 예를 들어 파일을 다운받는 async 함수를 사용합니다.

다운받는 파일이 매우 클때, 앱은 많은 자원을 소비하게 됩니다. 해당 파일을 파싱할 때 소비되는 프로세스의 파워도 굉장히 커지는데 

파싱 작업은 스레드를 계속해서 소비해야하는 작업이라 프로세스를 놔주지 않습니다.

이때 ui는 새로고침이 느러지게 되고 결국 어플은 버벅되게 됩니다. 이러한 경우에 바로 isolate를 다른 스레드, 다른 프로세스에 새로운 dart 프로그램을 실행시킵니다. 

이때 각각의 isolate는 서로를 block하지 않아 무거운 작업을 하면서도 유저에게 부드러운 UX를 제공할 수 있습니다. 

 

 

dart에서 eventLoop란?

싱글스레드에서 이벤트의 흐름과 비동기 작업을 관리하며 디스크i/o완료, 화면 터치, 타이머등의 이벤트가 발생하면 dart코드가 비동기적으로 실행되어 메인 실행 스레드를 차단하지 않고 발생한 이벤트를 처리하는 작업을 수행합니다.

eventLoop는 eventQueueMicrotask Queue를 기반으로 하며 eventQueue는 js의 메시지 큐와 유사하며 처리 대기중인 이벤트(I/O,  타이머, 클릭 이벤트, isolate 간의 메시지 등등)를 보유하고 있습니다. 

MicrotaskQueue는 eventQueue로 넘어가기 전에 비동기적으로 실행되고 종료되는 작은 작업 단위입니다.

dart eventLoop 먼저 MicrotaskQueue 대기열을 지속적으로 확인하여 작동하며, 대기열에 이벤트가 있는경우 eventQueue 다음 이벤트가 처리되기 전에 먼저 실행됩니다.

 

Dart는 이 eventLoop를 통해 복잡한 작업들을 효율적으로 처리한다고 합니다. eventLoop는 한번에 하나의 이벤트만을 처리합니다.

 

하나의 단일 스레드가 실행되는 순간 내부적으로 eventLoop를 통해  작업들을 처리하고 더 이상 진행할 task가 없다면 eventLoop는 외적으로 전달되는 각종 이벤트를 순서대로 처리하게 됩니다.

 

Future Stream또한 eventQueue 등록이되고 eventLoop 통해서 처리됩니다.