Flutter 之 Isolate

在Dart中实现并发可以使用Isolate。
Isolate翻译过来是孤立、隔离的意思。它是类似于线程但不共享内存的独立运行的worker,是一个独立的Dart程序执行环境,默认的执行环境就是一个main isolate。所有的Dart代码都运行在某个isolate中,代码只能使用所属isolate的类和值。不同的isolate可以通过port发送message进行交流。(首字母大写的Isolate代表Isolate对象,小写的isolate代表一个独立的Dart代码执行环境)

image.png

一个Isolate对象就是一个isolate的引用,通常不是当前代码所在的isolate,也就是说,当你使用Isolate对象时,你的目的应该是控制其他isolate。当你要spawn(产生)一个新的isolate时,如果操作成功,当前isolate会接收到一个代表新isolate的Isolate对象。
isolate在它自己的事件循环(event loop)中执行代码,每个事件都可以在该isolate的微任务队列(microtask queue)中执行更小的任务。
Isolate对象允许其他isolate控制、监听它所代表的isolate的事件循环,例如当这个isolate发生未捕获错误时,可以暂停(pause)此isolate或获取(addErrorListener)错误信息。
controlPort识别并授予对isolate控制的权限,pauseCapability和terminateCapability会对某些控制操作进行权限保护。例如,暂停(pause)一个无pauseCapability的Isolate对象是不生效的。
由spawn操作创建的Isolate对象具有控制接口(control port)和控制该对象的能力(capability)。当然,用Isolate.Isolate构造方法创建的Isolate对象可以不必带由这些能力。
Isolate对象不能用SendPort发送给另一个Isolate对象,但是控制接口(control port)和能力(capability)是可以发送的,并且可以在另一个Isolate对象中用发送来的接口与能力创建一个新的Isolate对象。

external static Future spawn(
      void entryPoint(T message), T message,
      {bool paused: false,
      bool errorsAreFatal,
      SendPort onExit,
      SendPort onError,
      @Since("2.3") String debugName});

创建一个与当前isolate共享代码的isolate,entryPoint参数指定了调用产生的isolate的初始函数,入口函数(entry-point function)在新isolate中以message作为唯一参数被调用。(可以想到,默认的isolate以main()函数作为入口)
这个函数必须是可以以单一参数调用的全局函数或静态方法,也就是说,它应该是接收至少一个位置参数并且最多一个必要位置参数的编译时函数常量值。只要它能用一个参数来调用,它可以接收任意数量的可选参数。它不能是函数表达式或实例方法。
初始化消息(message)通常包含了一个SendPort,以便生产者和被产这互相交流。
如果paused参数赋值为true,那么这个isolate启动时就是entryPoint方法调用前的暂停状态,就想初始化时就调用了isolate.pause(isolate.pauseCapability)一样。要回复运行,可以调用isolate.resume(isolate.pauseCapability)。
如果errorsAreFatal、onExit、onError参数被赋值,就相当于在isolate启动前,setErrorsFatal,addOnExitListener和addErrorListener分别以相应参数调用。
如果忽略errorsAreFatal参数,平台会以默认行为或者继承自当前isolate的行为来处理错误。
你也可以对返回的isolate调用setErrorsFatal、addOnExitListener和addErrorListener等方法,但是除非isolate以pause状态启动,它这些方法调用前可能已经执行完毕了。

import 'dart:isolate';

void main(List arguments) {
  // 创建一个消息接收器 
  var receivePort = ReceivePort();
  // 创建一个具有发送器的isolate,第一个参数为新的isolate的entryPoint,第二个是传的是当前
  Isolate.spawn(isolateOther, receivePort.sendPort);
  // 主isolate接收持有主进程发送器的isolate发过来的消息
  receivePort.listen((message) {
    if(message is SendPort) {
      message.send('已收到子isolate的发送器');
    }else {
      print('接到子isolate消息:'+message);
    }
  });
}

// 内存隔离的新的isolate的具体业务逻辑函数
void isolateOther(SendPort sendPort) {
  // 创建一个消息接收器
  var receivePort = ReceivePort();
  // 通过传过来的mainisolate的sendport(发送器) 将当前isolate的发送器发到mainisolate
  sendPort.send(receivePort.sendPort);

  sendPort.send('你收到我的消息了吗');
  receivePort.listen((message) {
    print('接到主isolate消息:'+message);
  });
}

你可能感兴趣的:(Flutter 之 Isolate)