dart isolate 개념 알아보기

flunge·2022년 1월 13일
2

Dart

목록 보기
2/2

isolate

dart는 싱글 스레드 환경이다. 비동기 프로그래밍을 지원하기 때문에 서버에서 데이터를 불러오며 ui를 그릴 수 있지만 불러오는 데이터가 크거나 어떤 복잡한 로직을 실행하면 버벅이는 모습을 볼 수 있다. 이런 현상을 해결하기 위해 구글링하다 찾게 되는것이 isolate이다.

isolate를 이용한 병렬작업은 자바에서의 멀티 스레딩과 비슷하지만 차이가 있다면 하나의 isolate가 하나의 스레드를 가지고 있다는 것이다.

All dart code runs in an isolate
one Isolate contains memory and an event loop and that's where all the code runs

하나의 isolate는 별도의 메모리와 하나의 스레드, 이벤트 루프를 가지고 있다. flutter앱도 main isolate에서 실행된다. 이러한 점은 자바에서 여러 스레드가 하나의 메모리를 공유한다는 점에서 차이가 있다.

synchronized

이 차이를 알아볼 수 있는 키워드가 있는데 자바의 synchronized키워드이다. 멀티 스레드 환경에서 여러 스레드가 하나의 변수를 동시에 접근하면 예상치 못한 결과를 초래할 수 있다. 그렇기 때문에 synchronized를 이용해 공유 변수에 대한 신뢰성을 보장할 수 있다.

There is no "synchronized" in Dart

하지만 dart에선 synchronized라는 키워드는 필요가 없다 그 이유가는 각각의 isolate는 메모리를 공유하지 않기 때문에 임계영역에 대한 문제가 발생하지 않기 때문이다.

예제

Singlton객체를 이용한 예제를 통해 알아보면

class MySingleton{
  
  static final MySingleton _instance = MySingleton._internal();
  
  factory MySingleton(){
    return _instance;
  }
  
  MySingleton._internal(){
    print('MySingleton._internal');
  }
  
}

MySingleton이라는 이름의 클래스를 dart코드로 작성한다.

void main() async{
  MySingleton my1 = MySingleton();
  MySingleton my2 = MySingleton();
  
  print(my1.hashCode);
  print(my2.hashCode);
  print(my1 == my2);
  
}

그 후 main메소드에서 두 개의 객체를 만들고 3줄을 출력해본다.

결과는 두 객체가 같은 값을 출력하고 비교했을 때도 같다고 나온다.

void main() async{
  MySingleton my1 = MySingleton();
  MySingleton my2 = MySingleton();
  
  print(my1.hashCode);
  print(my2.hashCode);
  print(my1 == my2);
  
  
  Isolate? isolate;

  isolate = await Isolate.spawn<String>((message) { 

    MySingleton my3 = MySingleton();
    print(my3.hashCode);
  }, 'message');
  
}

이제 간단한 isolate를 만들고 그 안에서 my3를 생성해본다.

true아래에 MySingleton._internal이 한번 더 출력되고 그 아래에 hashcode가 위에서의 값과 다르다. 이 말은 싱글톤 객체가 2번 생성 되었고 위와 아래의 객체가 다른 객체라는 의미이다.
싱글톤 객체는 프로그램 전체에서 하나의 객체만 만들고 그 객체를 여기저기서 공유해서 사용하는 객체인데 위에서 true가 찍히기 전까진 그렇게 작동하다 그 아래에는 다르게 작동한다.

isolate = await Isolate.spawn<String>((message) { 
  
  print('----- new isolate ------');
  MySingleton my3 = MySingleton();
  MySingleton my4 = MySingleton();
  
  print(my3.hashCode);
  print(my4.hashCode);
  print(my3 == my4);
}, 'message');

isolate안의 메소드를 조금 수정하고 실행해보자

새로운 isolate안에서는 같은 객체를 공유한다는 것을 볼 수 있다. 이런 결과가 나오는 이유는 각각의 isolate가 서로 다른 메모리를 가지고 있기 때문이다.
main메소드가 실행되는 isolate와 그 안에서 새로 만든 isolate가 다른 메모리를 가지고 있기 때문에 싱글톤 객체가 main에서 한번, 새로만든 곳에서 한번 생성된 것이다.

마치며

한 마디로 정리하자면 새로운 isolate를 생성하는 것은 새로운 dart 프로그램을 실행하는 것과 같다고 할 수 있을 것 같다.

다음 글에서는 isolate간의 통신과 async/await을 이용한 비동기 프로그래밍과의 차이를 알아볼 것이다.

0개의 댓글