Dart와 Isolate(Flutter에서 멀티 스레드 흉내내기)

김흰돌·2024년 10월 25일

Flutter를 이용해 앱을 개발하는데
내가 구현해야할 부분이 안드로이드와 iOS에서의 백그라운드 동작을 구현하는 것이였다.
백그라운드를 구현하면서 로그에 계속 보이는 단어가 바로 Isolate였다.

Isolate란?

Flutter에서 Isolate는 Dart의 고유한 개념이다.
기본적으로 단일 스레드로 동작하는 Dart에서 병렬 처리를 가능하게 하는 방법이다.
Isolate는 독립된 메모리 공간을 가진 별도의 실행 환경을 제공해서 오래 걸리는 작업을 메인 스레드와 분리해 처리할 수 있도록 한다.
이를 통해 메인 스레드의 성능에 영향을 주지 않으면서 백그라운드에서 작업을 수행할 수 있다.



Isolate와 멀티 스레드의 차이점은?

Isolate와 멀티 스레드는 병렬 처리를 가능하게 한다는 공통점이 있지만 구조와 동작 방식에서 몇 가지 중요한 차이점이 있다.

메모리 관리

Isolate는 메모리를 격리하여 안전하지만 데이터 전달에 복사 비용이 든다. 일반 스레드는 메모리를 공유해 빠르게 접근 가능하지만 동기화 문제를 신경 써야 한다.

데이터 전달 방식

Isolate는 메시지 패싱을, 일반 스레드는 직접 접근을 사용한다.

실행 환경

Isolate는 독립된 환경으로 멀티코어 최적화가 되어 있으며 스레드는 OS에 의해 관리된다.

사용 용도

Isolate는 Flutter에서 UI 차단을 방지하는 데 유리하고 멀티 스레드는 시스템 전반의 복잡한 동기화 작업에 유리하다.



사용 예제

import 'dart:isolate';

void heavyTask(SendPort sendPort) {
  int result = 0;
  for (int i = 0; i < 1000000000; i++) {
    result += i;
  }
  sendPort.send(result);
}

void main() async {
  ReceivePort receivePort = ReceivePort();
  await Isolate.spawn(heavyTask, receivePort.sendPort);
  
  receivePort.listen((message) {
    print("Result from isolate: $message");
    receivePort.close();
  });
}

ReceivePort

  • ReceivePort는 메인 Isolate에서 결과를 받을 통신 채널로 사용된다.
  • 즉 ReceivePort는 메인 Isolate에서 메시지를 받을 수 있는 리스너 역할이다.
  • sendPort() 함수는 다른 Isolate로 데이터를 보낼 때 사용된다.
  • listen() 함수를 통해 다른 Isolate에서 보낸 메시지를 받는다.
  • close() 함수는 ReceivePort를 닫아주는 역할을 한다.

dart:isolate

  • spawn() 함수를 통해 새로운 Isolate를 생성하고 생성한 Isolate에서 heaveTask 함수를 실행한다.
  • 첫 번째 인자로 실행할 함수를, 두 번째 인자로 ReceivePort를 전달해 새 Isolate가 작업을 완료하면 결과를 메인 Isolate로 보낼 수 있도록 설정한다.
profile
Android, Flutter

0개의 댓글