前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >flutter isolate microTask

flutter isolate microTask

原创
作者头像
黑兔
修改2023-02-16 10:11:26
6410
修改2023-02-16 10:11:26
举报
文章被收录于专栏:羊了个羊羊了个羊

Isolate 线程(进程)

isolate开辟的线程是随机并发的

代码语言:javascript
复制
isolateDemo() {
  Isolate.spawn(func1, 10);
  Isolate.spawn(func2, 10);
  Isolate.spawn(func1, 10);
  Isolate.spawn(func2, 10);
  Isolate.spawn(func1, 10);
  Isolate.spawn(func2, 10);
}

func1(int num) {
  print('任务1');
}
func2(int num) {
  print('任务2');
}

输入结果:
I/flutter ( 1559): 任务1
I/flutter ( 1559): 任务2
I/flutter ( 1559): 任务2
I/flutter ( 1559): 任务1
I/flutter ( 1559): 任务1
I/flutter ( 1559): 任务2

isolate开辟的线程是在新的进程上开辟的,拥有完全独立的内存空间

代码语言:javascript
复制
int count = 10;
isolateDemo() {
  Isolate.spawn(func, 100);
  sleep(const Duration(seconds: 5));//睡眠5s,等待子线程执行完
  print('count = $count');
}

func(int num) {
  count = num;
  print('isolate.count = $count');
}

I/flutter ( 1559): isolate.count = 100
I/flutter ( 1559): count = 10

从结果上看,子线程修改完全局变量,主线程的count还是原来的值。要想从子线程同步执行结果,dart提供了接口port,监听port回调来获得子线程的回调结果。

代码语言:javascript
复制
int count = 10;
isolateDemo() async{
  ReceivePort receive = ReceivePort();
  Isolate iso = await Isolate.spawn(func, receive.sendPort);
  receive.listen((message) {
      count = message;
      print('接收到 新的count = $count');
      receive.close();//用完需关闭port
      iso.kill();
  });
  sleep(const Duration(seconds: 5));
  print('count = $count');
}

func(SendPort sendPort) {
  count = 100;
  sendPort.send(count);
  print('isolate.count = $count');
}

I/flutter ( 1559): isolate.count = 100
I/flutter ( 1559): count = 10
I/flutter ( 1559): 接收到 新的count = 100

compute 与 isolate的区别,compute是是在isolate的上再封装了一层。compute有返回值直接就可以接受。

代码语言:javascript
复制
const ComputeImpl compute = isolates.compute;
代码语言:javascript
复制
computeDemo() async{
  print('代码1');
  int num = await compute(func3,100) as int;
  print('num = $num');
  print('代码2');
}

int func3(int count){
  sleep(Duration(seconds: 5));
  return 1000;
}

I/flutter ( 1559): 外部代码1
I/flutter ( 1559): num= 1000
I/flutter ( 1559): 外部代码2

而且,await会堵塞下面的代码,直到compute执行完才继续往下执行。如果是isolate.spawn直接开辟的线程是不会堵塞往下的代码。

无论是compute 还是 isolate都必须在asyn函数内使用。

事件任务与微任务

在每一次事件循环中,Dart总是先去第一个microtask queue中查询是否有可执行的任务,如果没有,才会处理后续的event queue的流程

task run loop
task run loop
代码语言:javascript
复制
void futureDemo(){
  Future f1 = Future(() => null);

  Future f2 = Future(() => debugPrint('1'));
  f2.then((value) => debugPrint('4'));

  f1.then((value) {
    debugPrint('6');
  }).then((value) => debugPrint('8'));

  Future(() => debugPrint('2'));
  scheduleMicrotask(() {debugPrint('3');});
  debugPrint('5');
  //5 3 6 1 4 2
}

结果:
I/flutter ( 1559): 5
I/flutter ( 1559): 3
I/flutter ( 1559): 6
I/flutter ( 1559): 8
I/flutter ( 1559): 1
I/flutter ( 1559): 4
I/flutter ( 1559): 2

代码段执行顺序:主线程 - 队列(Future) - 微任务(scheduleMicrotask)

future和then分开写还是一起写,都是同一行执行语句。future执行完,马上就会执行相应的then、whenComplete

代码语言:javascript
复制
void futureDemo(){
  Future f1 = Future(() => null);
  f1.then((value) {
    debugPrint('6');
    scheduleMicrotask(() {debugPrint('7');});//f1、then、whenComplete同属一执行语句。每个事件任务执行完会再去轮询微任务
  }).then((value) => debugPrint('8')).whenComplete(() => debugPrint('9'));

  Future f2 = Future(() => debugPrint('1'));
  f2.then((value) => debugPrint('4'));

  Future(() => debugPrint('2'));
  scheduleMicrotask(() {debugPrint('3');});//微任务
  debugPrint('5');
  //5 3 6 8 9 7 6 1 4 2
}

I/flutter ( 1559): 5
I/flutter ( 1559): 3
I/flutter ( 1559): 6
I/flutter ( 1559): 8
I/flutter ( 1559): 9
I/flutter ( 1559): 7
I/flutter ( 1559): 1

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Isolate 线程(进程)
  • 事件任务与微任务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档