为了解决多线程带来的并发问题,Dart 使用 isolates 替代线程,所有的 Dart 代码均运行在一个 isolates 中。每一个 isolates 有自己的堆内存以确保其状态不被其它 isolates 访问。这样保证每个isolate只有一个线程,不存在锁定与同步问题。
单个isolate模型:
![](https://img.haomeiwen.com/i8701235/c57bd950df00f5b1.png)
两个isolate模型
![](https://img.haomeiwen.com/i8701235/80cc0ebe14daceae.png)
不同isolate如何通信:
使用ReceivePort与SendPort,是隔离区之间唯一的通信方式。
spawn方法
创建一个与当前isolate共享代码的isolate(并不是共享内存,仅代码)
spawn操作提供的Isolate对象将具有控制隔离所需的控制端口和功能
spawn<T>(
void entryPoint(T message),
T message, {
bool paused: false,
bool errorsAreFatal,
SendPort onExit,
SendPort onError
}
) → Future<Isolate>
entryPoint参数指定了调用产生的isolate时的初始函数,初始化消息(message)通常包含一个SendPort,以便生产者与被产者互相交流。
await Isolate.spawn(echo, receivePort.sendPort);
sendPort都是receivePort定义出来的
echo方法的定义:
echo(SendPort sendPort) async {
}
宿主Isolate的sendPort作为参数给到echo的Isolate
完整代码:
import 'dart:async';
import 'dart:isolate';
import 'package:http/http.dart' as http;
main() async {
ReceivePort receivePort = ReceivePort();
await Isolate.spawn(echo, receivePort.sendPort);
// 'echo'发送的第一个message,是它的SendPort
SendPort sendPort = (await receivePort.first) as SendPort;
var msg = await sendReceive(sendPort, "test1");
print('received $msg');
msg = await sendReceive(sendPort, "test2");
print('received $msg');
}
// 新isolate的入口函数
echo(SendPort sendPort) async {
// 实例化一个ReceivePort 以接收消息
var port = new ReceivePort();
// 把它的sendPort发送给宿主isolate,以便宿主可以给它发送消息
sendPort.send(port.sendPort);
// 监听消息
await for (var msg in port) {
String data = msg[0] as String;
SendPort replyTo = msg[1] as SendPort;
//在此ioslate中处理,并将结果发给宿主,这里将数据原封不动返回
String result = data ;
replyTo.send(result );
if (data == "test2") port.close();
}
}
/// 对某个port发送消息,并接收结果
Future sendReceive(SendPort port, msg) {
ReceivePort response = new ReceivePort();
//发送消息数据给echo isolate
port.send([msg, response.sendPort]);
//response.first即为从echo isolate接收到的数据
return response.first;
}
参考:
https://medium.com/dartlang/dart-asynchronous-programming-isolates-and-event-loops-bffc3e296a6a
网友评论