Concurrency and isolates | Flutter
Concurrency | Dart
์ด๋ฒ ๊ธ์์๋ Isolate์ ๋ํด์ ๋ค๋ค๋ณด๋๋ก ํ๊ฒ ๋ค.
Flutter๋ก ๊ฐ๋ฐํ๋ค ๋ณด๋ฉด ์์ฐ์ค๋ฝ๊ฒ ๋ฃ๊ฑฐ๋ ์ฐพ์๋ณด๊ฒ ๋๋ ๊ธฐ๋ฅ์ด ๋ฐ๋ก Isolate ๊ธฐ๋ฅ์ผ ๊ฒ์ด๋ค.
Isolate๊ฐ ๋ฌด์์ด๋ฉฐ, ์ ํ์ํ ๊ธฐ๋ฅ์ธ์ง, ์ด๋ป๊ฒ ์ฌ์ฉํด์ผ ํ๋์ง, ์ด๋ค ๋จ์ ๋ค์ด ์๋์ง์ ๋ํด์ ์์ ๋ฅผ ์ดํด๋ณด๋ฉฐ ์ฐจ๊ทผ์ฐจ๊ทผ ๊ธ์ ์์ฑํด ๋ณด๋๋ก ํ๊ฒ ๋ค.
๋จผ์ Isolate๋ ๋ฌด์์ธ์ง์ ๋ํด์ ์์๋ณด๋๋ก ํ์.
Isolate๊ฐ ๋ฌด์์ธ์ง ์์๋ณด๊ธฐ ์ํด Dart ๊ณต์๋ฌธ์์์ ๋ด์ฉ์ ํ์ธํด๋ณด์๋ค.
Isolate๋ Dart ํ๋ก๊ทธ๋จ์์ ์คํ๋๋ ๊ณ ์ ํ ์์ ๋จ์์ ๋๋ค. ๊ฐ Isolate๋ ์์ ๋ง์ ๋ฉ๋ชจ๋ฆฌ์ ์คํ ์ค๋ ๋๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ๋ค๋ฅธ Isolate์ ์ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ์ง ์์ต๋๋ค. ์ด๋ ์ผ๋ฐ์ ์ธ ์ค๋ ๋ ๋ชจ๋ธ๊ณผ ๊ตฌ๋ณ๋๋ ์ ์ ๋๋ค.
Isolate ๊ฐ ํต์ ์ ๋ฉ์์ง ํจ์ฑ์ ํตํด ์ด๋ฃจ์ด์ง๋๋ค. ์ด๋ก ์ธํด ๋ฐ์ดํฐ ๋๊ธฐํ ๋ฌธ์ ๋ฅผ ํผํ ์ ์๊ณ , ๊ฐ๊ฐ์ Isolate๊ฐ ๋ ๋ฆฝ์ ์ผ๋ก ๋์ํ ์ ์์ต๋๋ค.
๋ฉ์ธ Isolate๋ Flutter ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฃผ UI ์ค๋ ๋์ ์ฐ๊ฒฐ๋ฉ๋๋ค. ๋ณต์กํ ๊ณ์ฐ์ด๋ ํ์ผ I/O ์์ ์ด ๋ฉ์ธ Isolate์์ ์คํ๋๋ฉด UI๊ฐ ๋๋ ค์ง ์ ์๊ธฐ ๋๋ฌธ์, ์ด๋ฌํ ์์ ์ ๋ค๋ฅธ Isolate๋ก ๋ถ๋ฆฌํ์ฌ ์คํํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
์์ ๋ด์ฉ์ด ๊ณต์๋ฌธ์์์ ์ค๋ช ํ๊ณ ์๋ ๋ด์ฉ์ธ๋ฐ, Isolate์ ๋ํ ๊ฐ๋ ์ ์ฒ์ ์ ํ๋ค๋ฉด ๋น์ฐํ ํ ๋ฒ์ ์ดํด๋ ์๋์ค๊ฑฐ๋ผ ์๊ฐํ๋ค.
Isolate๊ฐ ๋ฌด์์ธ์ง์ ๋ํด์ ์ข ๋ ํ์ด์ ์ ์ํด ๋ณด์๋ฉด, Isolate๋ Flutter, Dart์์ ์ฌ์ฉ๋๋ ์ผ์ข ์ ๋ ๋ฆฝ๋ ์คํ ๋จ์์ ๊ฐ๋ ์ด๋ค.
์ฝ๊ฒ ๋งํด์ ํ๋์ ํ๋ก๊ทธ๋จ ๋ด์์ ๋ณ๋์ ๋ฉ๋ชจ๋ฆฌ(Memory) ๊ณต๊ฐ๊ณผ ์ค๋ ๋(Thread)๋ฅผ ๊ฐ์ง๋ ๋
๋ฆฝ์ ์ธ ์คํ ํ๊ฒฝ์ ์๋ฏธํ๋ ๊ฒ์ด๋ค.
๋ณ๋์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์์ ์คํ๋๋ ํ๊ฒฝ์ด๋ฏ๋ก ๋น์ฐํ Isolate ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ์ง ์๊ฒ ๋๋ฉฐ, ํต์ ์ด ํ์ํ ๊ฒฝ์ฐ ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์๋ค.
์ง๊ธ๊น์ง์ ์ค๋ช ์ ๋ณด๋ฉด ๊ตฌ์กฐ๊ฐ ๋ฉํฐ์ค๋ ๋ฉ๊ณผ ์ ์ฌํ๋ค๊ณ ๋ณผ ์ ์์ด ๊ฐํน Isolate๋ฅผ ๋ฉํฐ์ค๋ ๋๋ก ์ค๋ช ํ๋ ๊ธ๋ค์ด ์๋๋ฐ, ๋ฉํฐ์ค๋ ๋์ ๋ณต์ก์ฑ๊ณผ ๋๊ธฐํ ๋ฌธ์ ๋ฅผ ํผํ๋ฉด์๋ ๋ณด๋ค ์์ ํ ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ์ด์ ์ ์ ๊ณตํ๊ธฐ ์ํด ์ค๊ณ๋์๋ค๋ ๊ฒ์ด ์ฐจ์ด์ ์ด๋ผ ๋ณด์๋ฉด ๋๋ค.
Isolate์ ๋ํ ๊ฐ๋ ์ด ๋ช ํํ ์กํ์ง ์์๋๋ผ๋ ์์ง์ ์ ํ ๋ฌธ์ ๋ ๊ฒ์ด ์๊ธฐ์ ์ฒ์ฒํ ์ดํดํ๋ฉด์ ๋ค์ ๋ด์ฉ๋ค์ ์ดํด๋ณด๋๋ก ํ์.
Isolate๊ฐ ๋ฌด์จ ๊ธฐ๋ฅ์ธ์ง๋ ์๊ฒ ๋๋ฐ, ๋๋์ฒด ์ ํ์ํ ๊ฑธ๊น ?
์ด ๋ถ๋ถ์ ์ดํดํ๊ธฐ ์ํด์๋ Flutter, Dart์ ์์ ํ๊ฒฝ์ ๋ํ ์ดํด๊ฐ ํ์ํ๋ค.
Flutter๋ Dart ์ธ์ด๋ก ๊ฐ๋ฐ๋์ด์ง ํ๋ ์์ํฌ๋ผ๋ ๋ถ๋ถ์ ์ด๋ฏธ ์๊ณ ์์ ๋ด์ฉ์ด๊ณ , ์ฑ๊ธ ์ค๋ ๋(Single-threaded) ํ๊ฒฝ์ผ๋ก ์คํ๋๋ค๋ ๊ฒ๋ ๋๋ถ๋ถ์ Flutter ๊ฐ๋ฐ์๋ผ๋ฉด ์๋ ๋ด์ฉ์ด๋ค.
์ฆ, ์ฑ๊ธ ์ค๋ ๋ ํ๊ฒฝ์์ ์คํ๋์ด ์ง๊ธฐ์ ๋ฉ์ธ ์ค๋ ๋(Main Thread) ๋๋ UI ์ค๋ ๋(UI Thread)๋ผ๊ณ ๋ถ๋ฆฌ๋ ์ค๋ ๋๊ฐ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ๊ณ , ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋๋ฉด ํด๋น ์์ ์ ์ฝ๋ฐฑ์ ์คํ์ํค๋ฉฐ, UI ์ ๋ฐ์ดํธ์ ๋ํ ๋๋๋ง ์์ ์ ์คํํ๊ฒ ๋๋ค.
ํ ๊ฐ์ ๋จ์ผ ์ค๋ ๋๊ฐ ํ๋ฉด์ ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ๋ฅผ ํธ์ถํ๋ฉฐ, ์ฌ์ฉ์ ํ๋์ ์ฒ๋ฆฌํ๊ณ ๋ณต์กํ ์ฐ์ฐ๋ ์คํํ๋ค๊ณ ์ฝ๊ฒ ์๊ฐํด๋ณด๋ฉด ์ดํด๊ฐ ๋ ๊ฒ์ด๋ค.
๋ง์ผ ์คํ์ด ์ง์ฐ๋๊ฑฐ๋ ํฐ ์์ ์ด ํฌํจ๋์ด ์๋ค๋ฉด UI๊ฐ ๋ฒ๋ฒ ์ด๋(Jank) ์น๋ช ์ ์ธ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๊ฒ๋๋ค.
๊ณผ์ฐ ์ผ๋ง๋ง์ ์๊ฐ์ ์์ ์ด ์ฒ๋ฆฌ๋์ด์ผ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๊ฑธ๊น ?
Flutter๋ 60ํ๋ ์(์ต๋ 120ํ๋ ์)์์ ์ต์ ์ ํผํฌ๋จผ์ค๋ฅผ ๋ชฉํ๋ก ํ๋๋ฐ, ํด๋น ํ๋ ์์ ์ต์ ํํ๊ธฐ ์ํด์ 16ms๋ง๋ค UI๋ฅผ ์
๋ฐ์ดํธํ๋ค๊ณ ์๋ ค์ ธ์๋ค.
๋งค ์ด 60ํ๋ ์์ด ๋๋๋ง ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์, ์ ํํ๋ 16.67ms ๋ด์ ๋๋๋ง์ด ๋์ด์ผ ํ๋ ๊ฒ์ด๊ณ , 120ํ๋ ์์ธ ๊ฒฝ์ฐ๋ 8.33ms ๋ด์ ์
๋ฐ์ดํธ๊ฐ ๋์ด์ผ ์ต์ ์ UI ํผํฌ๋จผ์ค๋ฅผ ๋ณด์ฌ์ค ์ ์๋ ๊ฒ์ด๋ค.
ํ๋ฉด ์ ๋ฐ์ดํธ๊ฐ ํด๋น ๊ธฐ์ค์ ๋์ด์๊ฒ ๋๋ฉด ํ๋ฉด ์ง์ฐ(Jank)์ด ๋ฐ์ํ์ฌ ์ฌ์ฉ์์๊ฒ ์ข์ง ์์ ๊ฒฝํ์ ์ ๊ณตํ๊ฒ ๋๋ฉฐ ์ฑ๋ฅ ์ ํ๊ฐ ๋ฐ์ํ ์ ์๊ฒ ๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ค์ ์ฌ์ ์ ํด๊ฒฐํ์ฌ ์ต์ ์ ํผํฌ๋จผ์ค๋ฅผ ๋ฐํํ๊ธฐ ์ํด CPU ์ง์ฝ์ ์ธ ์์ ์ด๋ ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๋ฑ์ ๋ณต์กํ๊ณ ๋ฌด๊ฑฐ์ด ์์ ์ ๋ฉ์ธ ์ค๋ ๋(Main Thread)์ ๋ณ๋์ ๋ ๋ฆฝ์ ์ธ ํ๊ฒฝ์์ ์คํํ์ฌ Jank๋ฅผ ์ค์ด๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋ต์ฑ์ ์ ์งํ๋๋ฐ Isolate ๊ฐ๋ ์ด ํ์ํ ๊ฒ์ด๋ค.
Isolate์ ์ผ๋ฐ์ ์ธ ์์ ์ ์ด๋ป๊ฒ ๋ค๋ฅธ์ง๋ฅผ ๊ฐ๋จํ ์์ ๋ก ์ดํด๋ณด๋๋ก ํ์.
์์ ๋ ๋จ์ํ ๊ธฐ๋ฅ์ธ๋ฐ, CPU ์ง์ฝ์ ์ธ ๋ฌธ์ ๋ฅผ ์คํํ๋ ๋ฐ ์์ด UI๊ฐ ์ด๋ป๊ฒ ๋ฐ์ํ๋์ง๋ฅผ ๋น๊ตํ ์์ ์ด๋ค.
๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํ ๊ฒฐ๊ณผ๋ฅผ ํ์ํด์ฃผ๋ ๋จ์ํ ๊ธฐ๋ฅ์ธ๋ฐ, ์ด ๋ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐํํ๊ธฐ ์ ๊น์ง ๋ก๋ฉ ์ธ๋์ผ์ดํฐ๋ฅผ ๋ ธ์ถ์์ผ UI์ ์ฐจ์ด์ ์ ๋จ๋ฒ์ ์ดํดํ ์ ์๋๋ก ํ์๋ค.
while (index < 10000000000) {
index++;
}
Nomal ์๋ ๋ฐฉ์์๋ UI๊ฐ ๋ฉ์ถ๋ ํ์(์ฆ์ ์๋ํ๋ฉด ๋ก๋ฉ ์ธํฐ์ผ์ดํฐ๊ฐ ์๋ณด์;)์ ๋ช ํํ๊ฒ ๋ํ๋ด ์ฃผ๊ธฐ ์ํด์ 1์ด์ ๋๋ ์ด ํ ์๋ํ๋๋ก ํ์๊ณ , Isolate ๋ฐฉ์์ UI๊ฐ ๋ฉ์ถ์ง ์๊ธฐ์ ์ฆ์ ์์ ์ ์งํํ์๋ค.
Nomal | Isolate |
---|---|
๋จ์ํ ๊ธฐ๋ฅ์ ํตํด์๋ Isolate ๊ธฐ๋ฅ์ ์ฅ์ ์ ๋ฐ๋ก ์ ์ ์๊ฒ ๋๋ค.
๊ธฐ๋ฅ์ ๋จ์ํ๋๋ผ๋ 100์ต ๋ฒ์ ๋ฐ๋ณต๋ฌธ์ด ์๋๋๊ธฐ์ ์์ ์ ์๋ฃํ๊ธฐ ๊น์ง๋ ๋งค์ฐ ๊ธด ์๊ฐ์ด ํ์ํ๊ฒ ๋๋ค.
๋ค๋ฅธ ์์ ๋ฅผ ๋ณด๋๋ก ํ์.
์ด๋ฒ ์์ ๋ ์์์ ์ฌ์ฉํ ์์ ์ ๋์ผํ ์์ ์ ์ํํ๋ ๊ธฐ๋ฅ์ด์ง๋ง UI๊ฐ ๋ฉ์ถ๋ ํ์์ด ๋ฐ์ ํ์ ๋์ ์ฌ์ฉ์ ์ด๋ฒคํธ๊ฐ ์ด๋ป๊ฒ ์ฒ๋ฆฌ๋๋์ง๋ฅผ ๋น๊ตํ ์์ ์ด๋ค.
Nomal | Isolate |
---|---|
Nomal ๋ฐฉ์์์๋ UI๊ฐ ๋ฉ์ถ๊ณ ์ด๋ฒคํธ์ ๋ํ ๋ฐ์์ ์
๋ฐ์ดํธํ์ง ๋ชปํ๋ค๊ฐ ๋ฐ๋ณต๋ฌธ์ด ์ข
๋ฃ ๋์์ ๋์ ์
๋ฐ์ดํธ๊ฐ ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๋ง์ผ ์ฌ์ฉ์ ์ด๋ฒคํธ๊ฐ ์๋ฒ์ ๋ํ ์์ฒญ์ด์๋ค๋ฉด ์ด๋ ์ฌ๊ฐํ ์ํฉ์ ์ด๋ํ ์ ์์์ ๊ฒ์
๋๋ค.
๋ฐ๋ฉด Isolate์์๋ ์ํํ๊ฒ UI ์
๋ฐ์ดํธ๋ฅผ ์งํํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ด๋ ๊ฒ CPU ์ง์ค ์์
์ ๋ฉ์ธ ์ค๋ ๋(Main Thread)์์ ํ๊ฒ ๋๋ฉด ํ๋ ์์ ์ต์ ํํ๊ธฐ ์ํ 16ms(์ต๋ 8.3ms) ๋ด์ UI ์
๋ฐ์ดํธ๋ฅผ ์๋ฃํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ UI๊ฐ ๋ฉ์ถ๊ฒ ๋๋ ๊ฒ์ด๋ค.
๋ฐ๋ฉด Isolate๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด ๋ณ๋์ ๋
๋ฆฝ์ ์ธ ํ๊ฒฝ์์ ์์
์ ์งํํ๊ธฐ์ UI ์ค๋ ๋(UI Thread)๋ฅผ ๋ฐฉํดํ์ง ์๊ณ ๋งค๋๋ฌ์ด UI๋ฅผ ๋ํ๋ด ์ฃผ๋ฉด์ ๊ฒฉ๋ฆฌ๋ ๊ณต๊ฐ์์ ์์
์ด ๊ฐ๋ฅํ ๊ฒ์ด๋ค.
์ผ๋จ์ Isolate๊ฐ ๋ฌด์์ด๊ณ , ์ ์ฌ์ฉํด์ผ ํ๋์ง์ ์๊ฐ์ ์ผ๋ก ์ด๋ป๊ฒ ์ฐจ์ด๊ฐ ์๋์ง ์ด๋ ์ ๋๋ ์ดํด๋ ํ์ ๊ฒ์ด๋ผ ์๊ฐํ๋ค.
*์ ๋ชจ๋ฅด๊ฒ ๋ค๋ฉด, ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ๋ฉด์ ์ดํดํ์๋ฉด ๋ฉ๋๋ค !
์ง๊ธ๊น์ง ์ดํด๋ณธ ๋ด์ฉ์ผ๋ก๋ง ๋ณธ๋ค๋ฉด Isolate๋ ๋ฌด์กฐ๊ฑด ์ฌ์ฉํด์ผ ํ๋ ๊ธฐ๋ฅ ์ฒ๋ผ๋ณด์ธ๋ค.
๋ฉ์ธ ์ค๋ ๋(Main Thread)์ ๋ฐฉํด๋ฅผ ํ์ง ์์ผ๋ฉด์๋ ์ผ๋ง๋ ์ง ๋ณต์กํ ์์ ์ ์ฒ๋ฆฌํ ์ ์๋๊ฑฐ ์๋๊ฐ ?
๊ณผ์ฐ ๋ฌด์กฐ๊ฑด ์ฌ์ฉํด์ผ ํ๋ ๊ธฐ๋ฅ์ผ๊น ..? ์ผ๋ง๋ ๋ณต์กํ๊ณ ๋ฌด๊ฑฐ์ด ์์ ์ด์ด์ผ ํ ๊น ..?
Isolate๋ ์ถฉ๋ถํ ํ์ํ ๊ธฐ๋ฅ์ด๊ณ , ์๋น์ค๋ฅผ ์์ ์ ์ผ๋ก ๊ตฌ์ถํ๊ธฐ ์ํ ํ๋ฅญํ ํด๊ฒฐ์ฑ ์ด ๋ ์๋ ์๋ค.
ํ์ง๋ง ์ฃผ์ํด์ผ ํ ์ ๊ณผ ์ด๋ ์ผ์ด์ค์์ ๋์ ํด์ผ ํ ์ง ? ๋ฑ์ ๊ณ ๋ฏผํ์ฌ์ผ ํ๋ ๋ฌธ์ ๋ค์ด ์๋ค.
Isolate ๊ธฐ๋ฅ์ ํ์๋ก ํ๋ ์ผ์ด์ค์๋ ์ด๋ค ์์ ๋ค์ด ์๋์ง ๋จผ์ ์์๋ณด์.
๋ํ์ ์ธ ์์ ์ CPU ์ง์ฝ์ ์ธ ์์ ๋ค์ด ์๋ค.
๊ณ ํด์๋ ์ด๋ฏธ์ง๋ฅผ ์ฒ๋ฆฌํ๋ ์์ ์ด๋, ๋๊ท๋ชจ ํ์ผ์ ์ง๋ ฌํ/์ญ์ง๋ ฌํ, ๋ณต์กํ ์ฐ์ฐ ์์ ๋ฑ์ด ๋ํ์ ์ผ๋ก CPU ์์์ ๋ง์ด ์๋ชจํ ์ ์๋ ์์ ์ด๋ฏ๋ก ๋ฉ์ธ ์ค๋ ๋(Main Thread)๊ฐ ์ฐจ๋จ๋ ๊ฐ๋ฅ์ฑ์ด ์๋ค๊ณ ํ๋ค. ๊ทธ ์ธ์๋ ์๋ง์ ์์ ๋ค์ด ๋ฉ์ธ ์ค๋ ๋(Main Thread)์ ์ํฅ์ ๋ฏธ์น ์ ์๋ค.
๊ทธ๋ ๋ค๊ณ ํด์ ์ด ๋ชจ๋ ์์ ๋ค์ ๋ฌด์กฐ๊ฑด Isolate๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๋ ๊ฒ์ ์๋๋ค.
Isolate๋ก ๊ตฌ์ถํ๊ฒ ๋๋ฉด ๊ณ ๋ คํด์ผ ํ ๋ฌธ์ ์ ๋ค์๋ ์ด๋ค ๊ฒ๋ค์ด ์์๊น ?
์์์๋ ์ค๋ช
ํ ๋ด์ฉ์ด์ง๋ง Isolate๋ ๋ณ๋์ ๋
๋ฆฝ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฌ์ฉํ๊ธฐ์ ์ง์ ์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ์ง ๋ชปํ๊ณ , ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ํตํด ๊ณต์ ๋ฅผ ํด์ผํ๋ค.
๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ์ง ๋ชปํ๋ค๋ ๊ฒ์ ๊ฐ๋จํ๊ฒ ๋งํด์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ์ง ๋ชปํ๋ค๋ ๊ฒ์ด๋ค. ๋ฉ์์ง ํจ์ฑ(Message Passing)์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๊ธฐ ์ํด ๋ฐ์ดํฐ ์ง๋ ฌํ/์ญ์ง๋ ฌํ์ ๊ณผ์ ์ด ํ์ํ๊ฒ ๋๋๋ฐ ์ด ๋์ ๋ณต์กํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ํจ์ฑํ๊ฒ ๋๋ฉด ์คํ๋ ค ์ฑ๋ฅ ์ ํ๊ฐ ๋ฐ์ํ ์๋ ์์ด์ ์ผ๋ฐ์ ์ผ๋ก ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ๋จ์ํ ๋ฐ์ดํฐ๋ง์ ์ ์กํ๋ค.
๋ ๋ฆฝ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ฐ์ง๋ค๋ ์๋ฏธ๋ฅผ ๋ณด๋ฉด Isolate ์์ฑ์๋ง๋ค ์๋ก์ด ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์ํ๋ค๋ ์๋ฏธ์ด๊ธฐ ๋๋ฌธ์ ํ์ ์ ์ธ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๋๋ฐ์ด์ค๋ผ๋ฉด ์ ํ์ ์ธ ์ํฉ์ด ์๊ธธ ์ ์๋ค.
์ด ์ธ์๋ ๋๋ฒ๊น , ํ ์คํธ ํ๊ฒฝ, ๋๊ธฐํ ํ์ด๋ฐ ๋ฑ์ ๊ณ ๋ คํด์ผ ํ ๋ฌธ์ ๋ค์ด ์๋ค.
์ค์ ๋ก Isolate๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋ ๋๋ถ๋ถ์ ๊ธฐ๋ฅ์ ์๋์ํค๋ ๋ฐ์๋ ๋ฌธ์ ๊ฐ ์๊ณ ๊ฐ ํ๊ฒฝ๋ง๋ค์ ์๋น์ค ๊ท๋ชจ๊ฐ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ Isolate ๋์ ์ ์ ๋ง์ ํ ์คํธ์ ๋๋ฒ๊น ํ ๋์ ์ ๊ณ ๋ คํด๋ณด๋ ๊ฒ์ ์ถ์ฒํ๋ค.
๋ณธ๊ฒฉ์ ์ผ๋ก Flutter์์ Isolate๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณด๋๋ก ํ์.
Flutter์์๋ spawn, compute ๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ๋ณ๋์ ๋ ๋ฆฝ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์์ ์์ ์ ์ํํ ์ ์๋๋ก ํด์ค๋ค.
spawn, compute ๋ชจ๋ ๋ ๋ฆฝ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์์ ์์ ์ ์ํํ ์ ์์ง๋ง ๊ฐ๊ฐ์ ๋ฐฉ์์๋ ์ฐจ์ด๊ฐ ์๋ค.
spawn์ Isolate๋ฅผ ์ง์ ์์ฑํ๊ณ ์ ์ดํ ์ ์๊ณ , ๋ ๋ฆฝ์ ์ธ ๋ฉ๋ชจ๋ฆฌ(Memory) ๊ณต๊ฐ๊ณผ ์ค๋ ๋(Thread)๋ฅผ ๊ฐ์ง๊ณ ์คํ๋์ด ๋ณต์กํ๊ณ ์ปค์คํฐ๋ง์ด์งํ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค. ๋ฐ๋ฉด, compute๋ ๊ณ ์์ค์ API๋ก ๊ฐ๋จํ๊ฒ ํจ์ ํํ๋ก Isolate ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ฉฐ, ์์คํ ์ด ์๋์ผ๋ก Isolate์ ์์ฑ๊ณผ ๊ด๋ฆฌ๋ฅผ ์ฒ๋ฆฌํด์ค๋ค (๋น์ฐํ compute๋ฅผ ์ฌ์ฉํด๋ ๋ ๋ฆฝ์ ์ธ ๋ฉ๋ชจ๋ฆฌ์ ์ค๋ ๋๋ฅผ ๊ฐ์ง).
์ฆ spawn์ ์ฌ์ฉํ๋ฉด Isolate๋ฅผ ์ง์ ์์ฑํ๊ณ ํด์ ํ๋ ๋ฑ์ ๋ชจ๋ ๊ด๋ฆฌ๋ฅผ ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ตฌํํด์ผ ํ๋ฉฐ, ๋ฐ์ดํฐ์ ์ ๋ฌ์ ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ํตํด์๋ง ์ด๋ฃจ์ด์ง๋ค. ๋ฐ๋ฉด compute๋ ์ด๋ฌํ ๊ณผ์ ์ ์๋์ผ๋ก ์ฒ๋ฆฌํด์ฃผ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ์ธ ์ค๋ ๋(Main Thread)์ ๋ฐํํ๊ฒ ๋๋ค.
๋จ์ํ ๋ณ๋ ฌ ์์ ์ compute๋ก ์ฒ๋ฆฌํ ์ ์์ง๋ง ๋ณต์กํ ๋ณ๋ ฌ ์์ ์ด ํ์ํ๋ค๋ฉด spawn์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ ํฉํ๋ค.
์ฐ์ ๋ณต์กํ spawn ์ฌ์ฉ ๋ฐฉ๋ฒ ๋ถํฐ ์์๋ณด๋๋ก ํ์.
spawn ์ฌ์ฉ ๋ฐฉ๋ฒ์ ์์์ผ compute ๋ฐฉ์์ด ์ด๋ป๊ฒ ์๋ ๋๋์ง๋ฅผ ๋จ๋ฒ์ ์ดํดํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ณต์กํ ๊ฒ๋ถํฐ ๋ฐฐ์๋ณด์ !
spawn์ ์ฌ์ฉํ Isolate ์คํ ์ ์ฐจ ๋ฐ ์ค๋ช ์ ๊ฐ๋จํ๊ฒ ๋ณด๋๋ก ํ์.
1. Isolate ์์ฑ
- spawn ํจ์๋ฅผ ์ฌ์ฉํด ์๋ก์ด Isolate ์์ฑ
- ์คํ๋ ์ฝ๋๋ฅผ ์ ์ํ๊ณ , ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ
2. ์คํํ๊ฒฝ
- ๋ ๋ฆฝ๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ๊ณผ ์ค๋ ๋๋ฅผ ๊ฐ์ง์ผ๋ก ๋ค๋ฅธ Isolate์๋ ์์ ํ ๋ถ๋ฆฌ๋ ํ๊ฒฝ
- ๋ฉ์ธ ์ค๋ ๋(Main Thread)์๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ณต์ ๋์ง ์๊ธฐ์ ๋ณ์๋ ๊ฐ์ฒด๋ฅผ ์ง์ ์ ์ผ๋ก ๊ณต์ ๋ถ๊ฐ
3. ๋ฉ์์ง ํจ์ฑ (Message Passing)
- ๋ฐ์ดํฐ ๊ตํ ๋ฐ ์ ๋ฌ์ด ๊ฐ๋ฅํ๊ณ , ์์ ๊ฒฐ๊ณผ๋ฅผ Main Isolate๋ก ์ ๋ฌ
- Send Port, Receive Port๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ ์ก/์์ ์งํ
4. ์์ ์คํ
- ๋ ๋ฆฝ๋ ํ๊ฒฝ์์ ํ ๋น๋ ์์ ์ ์ํ
- ๋ณต์กํ ๊ณ์ฐ, ํ์ผ I/O, ์ด๋ฏธ์ง ์ฒ๋ฆฌ ๋ฑ์ ์์
5. ์์ ์ข ๋ฃ ๋ฐ ์์ ํด์
- ์์ ์ด ์๋ฃ๋๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๊ณ ์์ ์ ์ข ๋ฃํ์ฌ ์์์ ํด์ ํ๊ณ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฐ๋ฉ
๊ฐ๋จํ๊ฒ ์ ์ฐจ๋ฅผ ๋ณด๋ฉด ์์ ์์๋๋ก ์์ ์ ์ํํด์ฃผ๋ฉด ๋๋ค.
spawn์ ์ฌ์ฉํด Isolate๋ฅผ ์์ฑํ๊ฒ ๋๋ฉด ๋ ์ด์ ์ฌ์ฉ์ด ํ์ํ์ง ์๋ ์์ ์๋ ๋ฐ๋์ Isolate๋ฅผ ํด์ ํ์ฌ์ผ ํ๋ค๋ ์ ์ ๊ผญ ๊ธฐ์ตํ์๊ธธ ๋ฐ๋๋ค.
Main Isolate ์ธ์ ์ถ๊ฐ์ ์ผ๋ก ์์ฑ๋ Isolate๋ Dart VM์ GC(Garbage Collector) ๋์์ด ์๋๊ณ ๋ด๋ถ ๊ฐ์ฒด๋ง GC(Garbage Collector)์ ๋์์ด ๋๊ธฐ ๋๋ฌธ์ ์๋์ผ๋ก ํด์ ๋์ง ์์ ๋ฆฌ์์ค๋ฅผ ๋ญ๋นํ๋ ์ํฉ์ด ๋ฐ์ํ์ง ์๋๋ก ์ฃผ์ํ์ฌ์ผ ํ๋ค.
Garbage Collection(GC) : ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ๊ธฐ๋ฅ์ผ๋ก ๋ ์ด์ ์ฌ์ฉํ์ง ์๋ ๊ฐ์ฒด๋ฅผ ์ฐพ์ ์๋์ผ๋ก ํด์ ํ๋ ์ญํ
spawn์ Dart ์ธ์ด์ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํฌํจ๋ ๊ธฐ๋ฅ์ผ๋ก ๋ณ๋๋ก ํจํค์ง๋ฅผ ์ถ๊ฐํ์ง ์๊ณ ์ฌ์ฉํ ์ ์๋ค.
spawn ํจ์๋ entryPoint, message๋ฅผ ํ์๋ก ์ค์ ํด ์ฃผ์ด์ผ ํ๋ค.
entryPoint๋ ์๋ก ์์ฑ๋ Isolate์์ ๊ฐ์ฅ ๋จผ์ ์คํ๋๋ ํจ์๋ก ํด๋น Isolate๊ฐ ์ํํ ์์ ์ ์ ์ํด ์ฃผ๋ฉด ๋๊ณ , message๋ ์ด ํจ์์ ์ ๋ฌ๋๋ ์ด๊ธฐ ๋ฐ์ดํฐ๋ก, entryPoint์ ์ ๋ฌํ ์ธ์(argument)๋ฅผ ์๋ฏธํ๋ค.
๋ฐ๋ผ์, spawn ํจ์๋ฅผ ์ฌ์ฉํ ๋ entryPoint์๋ ์คํํ ์์ ์ ์ ์ํ ํจ์๋ฅผ, message์๋ ๊ทธ ํจ์์ ์ ๋ฌํ ๊ฐ์ ์ค์ ํด ์ฃผ๋ฉด ๋๋ ๊ฒ์ด๋ค.
๊ธฐ๋ณธ ํํ๋ ์๋ ์ฝ๋์ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
Isolate.spawn(entryPoint, message);
entryPoint ํจ์๋ฅผ ๋ง๋ค์ด ๋ณด๋๋ก ํ์.
Isolate์์ ์๋๋ ๋ฌด๊ฑฐ์ด ์์ ์ ์ํด์ ๋ฃจํ๋ฅผ ์ฌ์ฉํ ์ฝ๋๋ฅผ ๋ง๋ค๋๋ก ํ๊ฒ ๋ค.
static void _runIsolate(SendPort message) {
int current = 0;
while (current < 10000000000) {
current++;
}
}
์ด์ด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํ ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ๋ํด์๋ ์ฝ๋๋ฅผ ํตํด ์์๋ณด๋๋ก ํ์.
message์๋ entryPoint์ ์ธ์ ๊ฐ์ ์ค์ ํ๊ฒ๋ ๋์ด์๋๋ฐ, SendPort ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
entryPoint์ ์ํ ์์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ message๋ฅผ ์ถ๊ฐํด ๋ณด๋๋ก ํ์.
SendPort ๊ฐ์ฒด์ send ํจ์๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ์ฌ ๋ฐํํ ์ ์๋ค.
static void _runIsolate(SendPort message) {
int current = 0;
while (current < 10000000000) {
current++;
}
message.send(current);
}
๋ฐํ๋ ๊ฒฐ๊ณผ๋ฅผ ์์ ํ๋๋ก ํด๋ณด์.
ReceivePort ๊ฐ์ฒด์ sendPort๋ฅผ spawn ์์ฑ์ ์ฌ์ฉํ ์ ์๊ณ , receivePort์ listen stream์ ๊ตฌ๋ ํด ๋ฐํ ๊ฒฐ๊ณผ๋ฅผ ์์ ๋ฐ์ผ๋ฉด ๋๋ค.
Future<void> _isolate() async {
final ReceivePort receivePort = ReceivePort();
Isolate.spawn(_runIsolate, receivePort.sendPort);
receivePort.listen((message) {
print(message);
});
}
์ด๋ฒ์ spawn ์์ฑ์ ๋ฉ์์ง๋ฅผ Isolate์ ์ด๊ธฐ ๊ฐ์ผ๋ก ์ ๋ฌํด์ฃผ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณด๋๋ก ํ์.
send ํจ์๋ Isolate๋ก ๋ถํฐ ๋ฐํ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ๋ฐ๋ ๊ฒ์ด๋ผ๋ฉด ์ด๋ฒ์ Isolate์ ๋ฐ์ดํฐ๋ฅผ ๋๊ฒจ์ฃผ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ด๋ฌํ ๋ฉ์์ง ํจ์ฑ(Message Passing)์ Dart ์ธ์ด์ ๋ฐ์ดํฐ ํ์ ์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ ๊ฐ์ฒด ๋ํ ๊ฐ๋ฅํ๋ค.
Isolate์ ๊ฒฐ๊ณผ๋ฅผ Main Isolate์์ ์ ๋ฌ ๋ฐ์ ํ์๊ฐ ์๋ค๋ฉด, SendPort ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ง ์์๋ ๋๊ธฐ์ ์๋ ์ฝ๋์ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
Future<void> _isolate() async {
Isolate.spawn(_runIsolate, 99);
}
static void _runIsolate(int initialCount) {
int current = initialCount;
while (current < 10000000000) {
current++;
}
print("current : $current, initialCount : $initialCount");
// flutter: current : 10000000000, initialCount : 99
}
๋ฌธ์ํ์ ์ ๋ฌํ ์๋ ์๋ค.
Future<void> _isolate() async {
Isolate.spawn(_runIsolate, "TYGER");
}
static void _runIsolate(String message) {
print("$message Velog !!");
// flutter: TYGER Velog !!
}
์ ์ํ, ๋ฌธ์ํ ์ธ์๋ ๋ฐ์ดํฐ ํ์ ์ ๋ชจ๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋ ์ฐธ๊ณ ํ์๋ฉด ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก Isolate๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๊ธธ ์ํ ๊ฒ์ด๋ค.
๊ทธ๋ฌ๊ธฐ ์ํด์๋ SendPort ๊ฐ์ฒด๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์, Isolate์๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ณ ๊ฒฐ๊ณผ ๊ฐ๋ ๋ฐ๊ธฐ ์ํ ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ๋ง๋ค์ด ๋ณด๋๋ก ํ์.
SendPort์ ์ด๊ธฐ ๊ฐ์ ๊ฐ์ง๋ Map ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํด๋ณด์.
final ReceivePort receivePort = ReceivePort();
final Map<String, dynamic> _data = {
"port": receivePort.sendPort,
"count": 99,
};
ํ์ ์บ์คํ ์ ์ฌ์ฉํด SendPort ๊ฐ์ฒด๋ฅผ ์ ๋ฌ ๋ฐ์ send ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด์ฃผ๋ฉด ๋๋ค.
static void _runIsolate(Map<String, dynamic> data) {
SendPort sendPort = data["port"] as SendPort;
int current = data["count"];
while (current < 10000000000) {
current++;
}
sendPort.send(current);
}
์์์ ๊ฒฐ๊ณผ๋ฅผ ๊ตฌ๋ ํ๋ ๊ฒ๊ณผ ๋์ผํ๊ฒ SendPort๋ฅผ ์์ฑํ ReceivePort ๊ฐ์ฒด์ listen์ ํตํด ์์ ํ๋ฉด ๋๋ค.
Future<void> _isolate() async {
final ReceivePort receivePort = ReceivePort();
final Map<String, dynamic> _data = {
"port": receivePort.sendPort,
"count": 99,
};
Isolate.spawn(_runIsolate, _data);
receivePort.listen((message) {
print(message);
});
}
Map ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋น์ฐํ class๋ก ๋ง๋ค์ด ์ฌ์ฉํ ์๋ ์๋ค.
class IsolateMessage {
final SendPort sendPort;
final int current;
const IsolateMessage({
required this.sendPort,
required this.current,
});
}
class๋ฅผ ์ฌ์ฉํด IsolateMessage ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ค ๋ค ์ฌ์ฉํ ์ ์๋ค.
Future<void> _isolate() async {
final ReceivePort receivePort = ReceivePort();
final IsolateMessage isolateMessage = IsolateMessage(sendPort: receivePort.sendPort, current: 99);
Isolate.spawn(_runIsolate, isolateMessage);
receivePort.listen((message) {
print("Result : $message");
// flutter: Result : 10000000000
});
}
IsolateMessage ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด SendPort์ send ํจ์๋ฅผ ์ฌ์ฉํด์ฃผ๋ฉด ๋๋ค.
static void _runIsolate(IsolateMessage message) {
int current = message.current;
while (current < 10000000000) {
current++;
}
message.sendPort.send(current);
}
Isolate์ ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ดค๋๋ฐ, ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ send ํจ์์๋ Dart ์ธ์ด์ ๋ฐ์ดํฐ ํ์ ๊ณผ ๊ฐ์ฒด ๋ชจ๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
class๋ฅผ ๋ง๋ค์ด์ฃผ์.
class IsolateResult {
final int result;
const IsolateResult({required this.result});
}
๊ฐ์ฒด๋ฅผ send ํจ์์ ํจ์ฑํ ์ ์๋ค.
static void _runIsolate(IsolateMessage message) {
int current = message.current;
while (current < 10000000000) {
current++;
}
IsolateResult result = IsolateResult(result: current);
message.sendPort.send(result);
}
๋ฉ์์ง ํจ์ฑ(Message Passing)์ Isolate ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ์ ์ผํ ๋ฐฉ๋ฒ์ด๊ณ , ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณต์ ํ์ง ์๊ธฐ ๋๋ฌธ์ SendPort, ReceivePort๋ฅผ ํตํด์๋ง ์ ๋ฌํ ์ ์๋ค๋ ์ ์ ์ดํดํ๊ณ ์์ผ๋ฉด ๋๋ค.
ํ์ง๋ง ๋ฐ์ดํฐ๊ฐ ๋ณต์กํ๊ฑฐ๋ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ ํฌ๋ค๋ฉด ์ง๋ ฌํ/์ญ์ง๋ ฌํ์ Main Isolate๊ฐ ์ด๋ฅผ ์ฒ๋ฆฌํ๋ ๋์ ์ง์ฐ(Jank)์ด ๋ฐ์ํด UI๊ฐ ๋๋ ค์ง๊ฑฐ๋ ๋ฒ๋ฒ ์ผ ์ ์์ด ์ฑ๋ฅ์ ์ํฅ์ ๋ฏธ์น์ง ์๋๋ก ์ถฉ๋ถํ ๊ณ ๋ คํ์ฌ ์ค๊ณํ์ฌ์ผ ํ๋ค๋ ์ ์ ์ฃผ์ํ์๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
๋ง์ฝ์ ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ์ฌ์ฉํด Isolate๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ง ์์๋ ๋๋ ์ผ์ด์ค๋ผ๋ฉด ์ด๋ป๊ฒ ์ฌ์ฉํ ์ ์์๊น ?
entryPoint์์ ์๋ฌด๋ฐ ์ธ์๋ฅผ ๋ฐ์ง ์๋๋ก ํ๊ณ message๋ฅผ null๋ก ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
ํ์ง๋ง ์ด๋ ๊ฒ ์ฌ์ฉํ๊ฒ ๋๋ฉด Isolate์ ์์
์ ํ์ธํ ์ ์์ ๋ฟ๋ง ์๋๋ผ Isolate๋ด์์๋ Main Isolate์ UI๋ฅผ ์ง์ ์ ์ผ๋ก ์
๋ฐ์ดํธ ํ ์ ์๊ธฐ ๋๋ฌธ์ ์์ฃผ ์ฌ์ฉ๋๋ ๋ฐฉ๋ฒ์ ์๋๋ค.
Future<void> _isolate() async {
Isolate.spawn(_runIsolate, null);
}
static void _runIsolate(_) {
int current = 0;
while (current < 10000000000) {
current++;
}
}
๊ทธ๋ผ์๋ ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ์ฌ์ฉํ ํ์๊ฐ ์๋ค๋ฉด ์ฐธ๊ณ ํ์๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค. ์๋ํ๋ฉด ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ์ฌ์ฉํ์ง ์์ผ๋ฉด์ ReceivePort๋ฅผ ๋ถํ์ํ๊ฒ ์ด์ด๋ ํ์๋ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด์ด์ ์์์๋ ์ธ๊ธํ ๋ด์ฉ์ด์ง๋ง ์ถ๊ฐ๋ก ์์ฑ๋ Isolate๋ Dart VM์ GC(Garbage Collector) ๋์์ด ๋์ง ์๋๋ค๋ ๋ถ๋ถ์ ์ธ๊ธํ์๋ค.
๋ฐ๋์ ๊ฐ๋ฐ์๊ฐ ํ์์ ์ํด์ ์์ฑ์ ํ๋ค๋ฉด ํด์ ๋ ํด์ฃผ์ด์ผ ํ๋ค๋ ์๋ฏธ์ด๋ค.
ํด์ ๋ฅผ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณด๋๋ก ํ๊ฒ ๋ค.
Isolate๋ฅผ ํด์ ํ๋ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ๋ค. kill ํจ์๋ง ์ฌ์ฉํด์ฃผ๋ฉด ๋๋ค.
์๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด Isolate๋ฅผ ์ ์ธํด์ผ ํ๋ค.
isolate.kill();
Isolate๋ Future ํ์ ์ด๊ธฐ ๋๋ฌธ์ ์์ฑ์ ์ธ์คํด์ค(Instance)๋ฅผ ๋ฐํํ๋ ค๋ฉด await ํค์๋๋ฅผ ์ฌ์ฉํด ์์ฑ์ ๊ธฐ๋ค๋ ค์ผ ํ๋ค.
final Isolate isolate = await Isolate.spawn(_runIsolate, null);
๋ฐํ๋ ์ธ์คํด์ค(Instance)๋ฅผ ์ฌ์ฉํด Isolate๋ฅผ ํด์ ํ์ฌ ๋ฉ๋ชจ๋ฆฌ์์ ์ ๊ฑฐํ ์ ์๋ค.
final Isolate isolate = await Isolate.spawn(_runIsolate, null);
isolate.kill();
ํด์ ๋๋ ์์ ์ด ์ค์ํ๊ฒ ๋๋ค. ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ ๋ฐ๊ณ ๋์ ํด์ ๊ฐ ๋์ด์ผ ํ๋ค.
ReceivePort๋ฅผ Isolate ๋ด์์ ์ด์ด ๋์๊ธฐ ๋๋ฌธ์ ๋ฉ์์ง ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๊ธฐ ์ ์ ๋จผ์ Isolate๊ฐ ํด์ ๋๋ค๋ฉด ReceivePort์ ๊ฒฐ๊ณผ๊ฐ ์์ ๋์ง ์๋๋ค.
ReceivePort์ ์์ ์ ๋ฐ๊ณ ๋์ ํด์ ํด์ฃผ๋ฉด ๋๋ค.
Future<void> _isolate() async {
final ReceivePort receivePort = ReceivePort();
final Isolate isolate =
await Isolate.spawn(_runIsolate, receivePort.sendPort);
receivePort.listen((message) {
print(message);
isolate.kill();
});
}
๋ฉ์์ง ํจ์ฑ(Message Passing)์ ์ฌ์ฉํ ๋์ ์ฃผ์ํ ์ ์ด ํ ๊ฐ์ง ๋ ์๋๋ฐ, ๋ฐ๋ก ReceivePort ๋ํ ๋ซ์์ค์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
Isolate๋ฅผ ํด์ ํ๊ฒ ๋๋ฉด ๋ ์ด์ ์ฌ์ฉ๋์ง ์๋ ReceivePort๋ GC(Garbage Collector)์ ์ํด ์๋์ผ๋ก ํด์ ๊ฐ ๋์ง๋ง ๋ช ์์ ์ผ๋ก ๋ซ์์ฃผ๋ ๊ฒ์ด ์ข๋ค.
ReceivePort๋ close ํจ์๋ฅผ ์ฌ์ฉํด ํฌํธ๋ฅผ ๋ซ์ ์ ์๋ค.
Future<void> _isolate() async {
...
receivePort.listen((message) {
print(message);
receivePort.close();
isolate.kill();
});
}
์์ฑ๋ Isolate๋ฅผ ํด์ ํ๊ณ , ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ์ํ ReceivePort๋ฅผ ๋ซ์ ์์์ ๋ช ํํ ํด์ ํ๊ณ , ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํ๋ฉฐ, ์ฝ๋์ ์์ ์ฑ์ ๋ํ ์ ์๋ค.
์ผ๋ถ Isolate๊ฐ ๋ฐ๋ณต์ ์ด๊ฑฐ๋ ์์ฃผ ์์ฑ๋์ด์ผ ํ๋ค๋ฉด ๋งค๋ฒ ์ด๊ณ ๋ซ๋ ๊ฒ์ด ๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ ํ ์ ์๊ธฐ์ ์์ ์ ์ธ ํด์ ์์ ์ ๊ณ ๋ คํ์ฌ ํจ์จ์ ์ธ ๊ด๋ฆฌ ๋ฐฉ๋ฒ์ ๊ณ ๋ฏผํด๋ด์ผ ํ ๊ฒ์ด๋ค.
spawn ๋ฐฉ๋ฒ์ ์ต์ ๋์ ๋ํด์๋ ์ดํด๋ณด๋๋ก ํ์.
paused
paused๋ Boolean ํ์
์ผ๋ก Isolate์ ์คํ ์ํ๋ฅผ ์ ์ดํ๋ ๋ฐ ์ฌ์ฉ๋๋ค. ๊ธฐ๋ณธ ๊ฐ์ false ์ํ์ด๊ณ , true๋ก ์ค์ ํ๋ค๋ฉด spawn์ผ๋ก Isolate๋ฅผ ์์ฑํ ๋์ ์ผ์ ์ ์ง ์ํ๋ก ์์ฑ์ด ๋์ด ๋ช
์์ ์ผ๋ก ์คํ์ ํ๊ธฐ ์ ๊น์ง๋ ๋๊ธฐ ์ํ๋ก ๋จ์ ์๊ฒ๋๋ค.
Isolate ์์ฑ ํ ์ด๊ธฐํ ์์
์ด๋ ํ๊ฒฝ ์ค์ ๋ฑ์ ์์
์ด ํ์ํ ๊ฒฝ์ฐ ๋๊ธฐ ์ํ๋ก ์ ํํ๊ธฐ ์ํด์ ์ฌ์ฉํ ์ ์๋ค.
๋๊ธฐ ์ํ๋ฅผ ํด์ ํ๊ณ ์ฌ๊ฐ ํ๊ณ ์ถ์ ๋์ resume ํจ์๋ฅผ ์ด์ฉํ๋ฉด ๋๋ค.
Future<void> _isolate() async {
final Isolate isolate = await Isolate.spawn(
_entryPoint,
message,
paused: true,
);
isolate.resume(isolate.pauseCapability!);
}
resume ํจ์ ์ฌ์ฉ์ ์์ฑ๋ Isolate์ pauseCapability๋ฅผ ์ฌ์ฉํด ๊ถํ์ ์ ๊ณตํ๋ฉด ๋๋ค.
errorsAreFatal
ํด๋น ์ต์
์ ์์ฑ๋ Isolate์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ๋ฐ์ํ ์ค๋ฅ๊ฐ ์น๋ช
์ (fetal)์ธ์ง๋ฅผ ๊ฒฐ์ ํ๋ ์ญํ ์ ํ๋ค.
Boolean ํ์
์ผ๋ก ๊ธฐ๋ณธ ๊ฐ์ true์ด๋ฉฐ, ์ค๋ฅ๊ฐ ๋ฐ์์ Isolate๋ ์ฆ์ ์ข
๋ฃ๋๋ค. ๋ง์ผ ์ฆ์ ์ข
๋ฃ๊ฐ ๋๊ธธ ์ํ์ง ์๋๋ค๋ฉด false๋ฅผ ์ ๊ณตํ๋ฉด ๋๊ณ ์ด ๊ฒฝ์ฐ Isolate๋ ๊ณ์ ์คํ๋๊ธฐ์ ํ์ ์์
์ ๋ณ๋๋ก ํด์ค์ผ ํ๋ค.
onExit
onExit๋ ๋ช
์นญ์์๋ ์ ์ ์๋ฏ์ด Isolate ์ข
๋ฃ ์์ ์ ์์ ํ๊ธฐ ์ํ ํ๋ผ๋ฏธํฐ์ด๋ค. ํด๋น ์๋ฆผ์ ๋ฉ์์ง๋ ํน๋ณํ ๊ฐ์ ๊ฐ์ง๋ ๊ฒ์ ์๋๋ฉฐ kill ํจ์ ์คํ์๋ ์ ์์ ์ผ๋ก ์ข
๋ฃ๊ฐ ๋์์ ๋์ ํธ์ถ์ ๋ฐ์ ์ ์๋ค.
์ข
๋ฃ ์์ ์ ํธ์ถ ๋ฐ๊ธฐ ๋๋ฌธ์ ํ์ํ ํ์ ์์
๋ฑ์ ์งํํ ์ ์๋ค.
์ฌ์ฉ ๋ฐฉ๋ฒ์ ์์์ ๋ฐฐ์ ๋ ReceivePort์ SendPort๋ฅผ ์์ฑํด์ ์ฌ์ฉํ ์ ์๋ค. ์ฌ๊ธฐ์ ์ค์ํ ๋ถ๋ถ์ spawn์ message์ ํฌํธ์ ์๋ก ๋ค๋ฅธ ํฌํธ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
Future<void> _isolate() async {
final exitPort = ReceivePort();
final Isolate isolate = await Isolate.spawn(
_entryPoint,
message,
onExit: exitPort.sendPort,
);
exitPort.listen((_) {
exitPort.close();
});
}
onError
onError๋ onExit์ ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋์ผํ๊ณ ์๋ฌ ๋ฐ์์ ๋ํ ์ ๋ณด๋ ์๋์ผ๋ก ๋ฉ์์ง๋ก ์ ๋ฌํด ์ฃผ์ง๋ง, send๋ฅผ ์ฌ์ฉํด ์ง์ ์ ๋ฌ ๋ฐ์ ์๋ ์๋ค.
์๋ฌ ๋ฐ์์ errorsAreFatal์ ์ค์ ์ ๋ฐ๋ผ ์ฆ์ ์ข
๋ฃ ์ํค๊ฑฐ๋ ์๋๋ฉด ์ข
๋ฃ๋ฅผ ์ํค์ง ์์ ์๋ ์๋๋ฐ, onExit์ ์ข
๋ฃ ์์ ๋ฑ์ ํธ์ถํด์ ํ
์คํธ ํด๋ณด๋ฉด ์๋ฌ์ ๋ฐ๋ฅธ Isolate ์ํ๋ฅผ ํ์ธํ ์ ์๋ค.
Future<void> _isolate() async {
final errorPort = ReceivePort();
final Isolate isolate = await Isolate.spawn(
_entryPoint,
message,
onError: errorPort.sendPort,
);
errorPort.listen((message) {
print("error : $message");
// flutter: error : [type 'int' is not a subtype of type 'String' in type cast, #0
errorPort.close();
});
}
debugName
๋ง์ง๋ง์ผ๋ก debugName์ ๋๋ฒ๊น ์ Isolate๋ฅผ ์๋ณํ ์ ์๋ ์๋ณ์๋ฅผ ์ถ๊ฐํ๋ ์ค์ ์ด๋ค. ๋๋ฒ๊น ๋๊ตฌ๋ IDE ์ฌ์ฉ์ ํจ์จ์ ์ผ๋ก ์๋ณํ ์ ์๋ค.
์ด์ธ์๋ ์์ฑํ Isolate์ ์ธ์คํด์ค ๋ฉ์๋์๋ ๋ค์ํ ๊ธฐ๋ฅ๋ค์ ์ ๊ณตํ๊ณ ์๋ค.
addOnExitListener์ addErrorListener๋ Isolate ์์ฑ ์ spawn ํจ์์์ ์ ๊ณตํ๋ ์ต์
๋ ํ๋ผ๋ฏธํฐ์ธ onExit์ onError์ ๋์ผํ ๊ธฐ๋ฅ์ ํฉ๋๋ค. ๊ฐ๊ฐ Isolate๊ฐ ์ข
๋ฃ๋ ๋์ ์๋ฌ๊ฐ ๋ฐ์ํ ๋ ํด๋น SendPort๋ก ์๋ฆผ์ ๋ณด๋ด๋ ์ญํ ์ ํ๊ฒ๋๋ฉฐ, removeOnExitListener์ removeErrorListener๋ ๊ฐ๊ฐ addOnExitListener์ addErrorListener๋ก ์ถ๊ฐํ ๋ฆฌ์ค๋๋ฅผ ์ ๊ฑฐํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
errorsAreFatal์ ๊ธฐ๋ฅ๊ณผ ๋์ผํ setErrorsFatal ํจ์๋ ์๋ค.
์ด๋ฒ์ compute ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณด๋๋ก ํ์.
compute๋ ๊ณ ์์ค์ API๋ก์ ๊ฐ๋จํ๊ฒ ํจ์ ํํ๋ก Isolate ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋ค. ์ฆ ์์คํ ์ด ์๋์ผ๋ก ์์ฑ๊ณผ ๊ด๋ฆฌ๋ฅผ ์ฒ๋ฆฌํด์ค๋ค.
๊ตฌ์กฐ ์์ฒด๊ฐ ๋จ์ํ๊ณ ์ฌํํ ํํ์ด๋ค.
compute๋ ๋ด๋ถ์ ์ผ๋ก Isolate์ ์์ฑ ๋ฐ ํด์ , ReceivePort, SendPort๋ฅผ ์ฌ์ฉํ ๋ฉ์์ง ํจ์ฑ(Message Passing)์ ์๋์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ์ ์ํํ ์์ ๊ณผ ์ด๊ธฐ ๋ฐ์ดํฐ๋ง ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
await compute(_callback, message);
callback์ ์ํํ ์์ ์ ๋ง๋ค์ด ์ฃผ๋๋ก ํ์.
spawn ์ฌ์ฉ์์๋ ReceivePort, SendPort๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ํ์์ง๋ง, compute๋ ํจ์ ์์ฒด๋ฅผ ๋ฐํํด์ฃผ์ด์ผ ํ๋ค.
static int _runIsolate(int value) {
int current = value;
while (current < 10000000000) {
current++;
}
return current;
}
์ ์ํ ์ธ์๋ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ํ์ ์ ์ธ์ ๊ฐ์ด๋ ๋ฐํ ๊ฐ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
int current = await compute(_runIsolate, 10);
compute๋ ๋น๋๊ธฐ์ ์ผ๋ก ์๋๋๊ธฐ์ then, catchError ๋ฑ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํด ์ฒ๋ฆฌํ์ฌ๋ ๋๋ค.
์๋์ผ๋ก Isolate๋ฅผ ํด์ ํด ์ฃผ๊ธฐ ๋๋ฌธ์, spawn ๋ฐฉ์๊ณผ ๋น๊ตํ๋ฉด ์ฝ๊ฒ ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค๋ ์ฅ์ ์ ์์ง๋ง ์ปค์คํฐ๋ง์ด์ง ๋ถ๋ถ์ด๋ ์ ์ด์ ํ๊ณ๊ฐ ์์ผ๋ ๊ธฐ๋ฅ์ ๊ท๋ชจ๋ ๋ณต์ก์ฑ, ์ฌ๋ฌ ์ผ์ด์ค ๋ฑ์ ๊ณ ๋ คํด์ ํจ์จ์ ์ธ ๋ฐฉ์์ผ๋ก ๊ตฌ์ถํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
์ด๋ฒ ๊ธ์์ Isolate๊ฐ ๋ฌด์์ด๊ณ , Flutter ๊ฐ๋ฐ์ ์ํด์ ์ ํ์ํ ๊ฐ๋ ์ธ์ง, ์ด๋ค ๊ฒฝ์ฐ์ ์ฌ์ฉํด์ผ ๋์์ด ๋๊ณ , ์ฃผ์ํ ์ ์ ๋ฌด์์ธ์ง์ ๋ํด์ ์์ฐจ์ ์ผ๋ก ์์ฑํด ๋ณด์๋ค.
์ถ๊ฐ์ ์ผ๋ก Isolate๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํด์ผ ํ๋์ง์ ๋ํ ์ฌ์ฉ ๋ฐฉ๋ฒ๋ ์์๋ณด์๋ค.
์ข ๋ ์๊ฐ์ ์ผ๋ก ์ฝ๊ฒ ์ดํดํ๊ณ ์ค์ ๋ก ์ ์ฉํด ๋ณผ ๋งํ ๊ธฐ๋ฅ๋ค๋ก ์์ ๋ฅผ ๋ง๋ค์ด ๋ณด๋ ค๊ณ ํ์ง๋ง ๋๋ถ๋ถ์ ์ผ์ด์ค์์๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ง์ผ๋ก๋ ์ถฉ๋ถํ ์ด์ ์์ด ๊ธฐ๋ฅ ์๋์ด ๊ฐ๋ฅํ๊ณ ๊ฐ์ ๋ก CPU ์ง์ฝ์ ์ธ ์์ ์ ์ถ๊ฐํด์ผ๋ง Isolate ์ฌ์ฉ์ ๋ํ ์๊ฐ์ ์ธ ์ฐจ์ด์ ์ด ๋ํ๋๊ธฐ ๋๋ฌธ์ ๋ค์ํ ์ผ์ด์ค์ ์์ ๋ฅผ ๋ง๋ค์ง ๋ชปํ ์ ์ด ์์ฌ์ด ๋ถ๋ถ์ด๋ค.
์ด ๋ถ๋ถ์ ์ค์ ๋ก ์ฌ์ฉ๋ ๋งํ ๊ธฐ๋ฅ๋ค์ ์ฌ๋ฌ ์ผ์ด์ค๋ฅผ ๊ณ ๋ คํ์ฌ ์์ ๋ฅผ ๋ง๋ค์ด ์ถ๊ฐ์ ์ผ๋ก ๊ธ์ ์์ฑํ๋๋ก ํ๊ฒ ๋ค.
Isolate์ ๋ํด์ ์๋ชป๋ ๋ด์ฉ์ด ์๊ฑฐ๋ ์ถ๊ฐ์ ์ผ๋ก ๊ถ๊ธํ์ ๋ถ๋ถ์ ํธํ๊ฒ ๋๊ธ ๋จ๊ฒจ์ฃผ์๋ฉด ํ์ธ ํ ๋น ๋ฅธ ๋ต๋ณ ๋๋ฆฌ๋๋ก ํ๊ฒ ์ต๋๋ค.
๊ฐ์ฌํฉ๋๋ค !
์ข์ ๋ด์ฉ ๊ฐ์ฌํฉ๋๋ค!