使用Isolate
的并发编程:与线程类似但不共享内存的独立区域,仅通过消息进行通信。
Library介绍
要使用Isolate
进行并发编程:
import 'dart:isolate';
复制代码
该Library主要包含下面几个类:
Isolate
:Dart执行上下文的隔离区。ReceivePort
:与SendPort
一起,是隔离区之间唯一的通信方式。SendPort
:将消息发送到其他ReceivePort
。
所有Dart代码都在隔离区中运行,代码只能访问同一个隔离区的类和值。不同的隔离区可以通过端口发送信息进行通信。
由spawn
操作提供的Isolate
对象将具有控制隔离所需的控制端口和功能。如有必要,可以使用Isolate.Isolate
构造函数创建新的隔离对象,而无需使用这些功能。
创建和启动Isolate
要创建Isolate
,你可以使用spawn
方法。必须为spawn
方法提供一个带有单个参数的“入口点”方法。 通常,此参数表示隔离应用于发送回通知消息的端口:
import 'dart:async';
import 'dart:isolate';
main(List<String> args) {
start();
print("start");
}
Isolate isolate;
int i =1;
void start()async{
//接收消息的主Isolate的端口
final receive = ReceivePort();
isolate = await Isolate.spawn(runTimer, receive.sendPort);
receive.listen((data){
print("Reveive : $data ; i :$i");
});
}
void runTimer(SendPort port){
int counter =0 ;
Timer.periodic(const Duration(seconds: 1), (_){
counter++;
i++;
final msg = "nitification $counter";
print("Send :$msg ;i :$i");
port.send(msg);
});
}
复制代码
运行上面的例子控制台的输出为:
start
Send :nitification 1 ;i :2
Reveive : nitification 1 ; i :1
Send :nitification 2 ;i :3
Reveive : nitification 2 ; i :1
Send :nitification 3 ;i :4
Reveive : nitification 3 ; i :1
复制代码
在上面的例子中,使用start
方法来创建一个端口并生成一个Isolate
。spawn
使用了两个参数,一个要执行的回调的函数runTimer
,和一个端口(SendPort
),回调可以用来将消息发送回调用者。端口是你与Isolate
通信的方式。这个例子将其设置为单向通行(从隔离区发送信息到接收者),但它可以是双向的。在start
方法的最后是监听来自定义isolate
的消息。
在控制台的输出中可以看出,两个Isolate
中打印的i的值并不一致,则说明Isolate
之间的内存并不是共享的。
停止Isolate等操作
在上面的例子中,Isolate
可以一直进行下去。如果想Isolate
停止运行,可以使用kill
方法。
void stop(){
print("kill isolate");
isolate?.kill(priority: Isolate.immediate);
isolate =null;
}
复制代码
上面的代码会杀死正在运行的Isolate
,并将引用置为null
。 Isolate.immediate
的优先级将在最近的机会干净地关闭Isolate
。
还可以暂停和恢复Isolate
的运行,分别对应Isolate
中的pause
方法和resume
方法。