Flutter 编程之Isolate

227 阅读2分钟

Isolate 理解

Isolate 是Dart中的线程,所有的Dart代码都运行在Isolate中

  • Dart中的线程是以隔离(Isolate)的方式存在
  • 每个Iso都有自己独立的,私有的内存块(多个线程不共享内存)
  • 没有共享内存,就不需要竞争资源,就不需要锁(不用担心死锁问题)
  • Isolate提供了Dart | Flutter的运行环境
  • 微任务队列、事件队列、事件轮询(EventLoop)都在Isolate中进行

Isolate的位置

isolate 位置.png

  • OS Thread :操作系统层面线程
  • Dart VM Thread:dart虚拟机层面线程
  • Isolate:系统默认只会创建一个,可以创建多个

Isolate多线程-创建

Isolate 类用来管理线程(创建、暂停、kill ),可以通过Isolate.spawn()Isolate.spawnUri()来创建。

  • Isolate.spawn():创建线程在当前文件调用函数
  • Isolate.spawnUri():调用指定文件的函数

spawn创建

Isolate.spawn(entryPoint, Message);
  • entryPoint: 是一个函数
  • Message:泛性的类型
Isolate.spawn(mutiThread, 'asdf');

void mutiThread(String message){
  print("当前线程" + Isolate.current.debugName!);
}

如果创建的回调函数名一样,表示还是同一个线程,创建不同的线程要用不同的函数名。

多线程通信

Iso多线程之间通信的方式Port

  • ReceivePort:初始化接收端口、创建发送端口、接收消息、监听消息
  • SendPort:将消息发送给ReceivePort

单向通信


//主线程
void mainThread(){
  print("current thread" + Isolate.current.debugName!);
  ReceivePort r1 = ReceivePort();
  SendPort p1 = r1.sendPort;
  
  Isolate.spawn(newThread, p1);
  
  //接受消息
  var msg = r1.first;
  
  r1.listen((message) {
    print(message);
    r1.close();
  });

}

void newThread(SendPort p1){
  print("current thread" + Isolate.current.debugName!);

  //发送消息给main线程
  p1.send("send msg to main");
}

接收消息又两种

  • var msg = r1.first
  • r1.listen, 如果不调用r1.close,会一直处于阻塞状态去监听

双向通信


//主线程
Future<void> mainThread() async {
  print("current thread" + Isolate.current.debugName!);
  ReceivePort r1 = ReceivePort();
  SendPort p1 = r1.sendPort;

  Isolate.spawn(newThread, p1);

  SendPort p2 = await r1.first;

  // 发送消息给新线程
  var msg = await sendToNewThread(p2, 'send msg to new thread');

  print('end');

}

Future<void> newThread(SendPort p1) async {
  print("current thread" + Isolate.current.debugName!);
  ReceivePort r2 = ReceivePort();
  SendPort p2 = r2.sendPort;

  //发送消息给main线程
  p1.send(p2);

  await for (var msg in r2){
    var data = msg[0];
    print('收到来自主线程的消息 $data');
    //给主线程回复消息
    SendPort replyPort = msg[1];
    replyPort.send(data);
  }

}


Future sendToNewThread(SendPort port,msg){

  ReceivePort response =  ReceivePort();
  port.send([msg,response.sendPort]);

  return response.first;
}