Appearance
源码:labs/dart/host/bin/runtime_concurrency/isolate_message_passing_demo.dart
- 原始路径:
labs/dart/host/bin/runtime_concurrency/isolate_message_passing_demo.dart - 类型:
dart
dart
// Dart Isolate 消息传递:SendPort / ReceivePort 演示
//
// 对应 docs 01-runtime-concurrency/14-dart-isolate-message-passing.md:
// 1. Isolate.spawn + SendPort/ReceivePort:跨 isolate 单向传消息
// 2. 消息是深拷贝副本:isolate 之间不共享对象
// 3. 可传数据类型:基础类型 / List / Map / TransferableTypedData
// 4. 双向通信:两个 isolate 各持一个 port 对
//
// 运行:dart run bin/runtime_concurrency/isolate_message_passing_demo.dart
import 'dart:async';
import 'dart:isolate';
import 'dart:typed_data';
// 子 isolate 入口:接收主 isolate 发来的 SendPort 与数据
void childIsolate(SendPort mainPort) {
// 子 isolate 再开一个 ReceivePort,把它的 SendPort 发回主 isolate → 双向
final childReceivePort = ReceivePort();
mainPort.send(childReceivePort.sendPort); // 1. 先回传自己的 port
childReceivePort.listen((message) {
if (message is List && message.isNotEmpty) {
final type = message[0];
if (type == 'echo') {
// 回传"深拷贝证明":修改副本看主 isolate 是否受影响
final data = (message[1] as List).cast<int>();
data[0] = 999; // 修改"副本"
mainPort.send(['echo_back', data, '我在子 isolate 改了这个 List 的首元素']);
} else if (type == 'compute') {
// 演示把 CPU 重活搬过来
var sum = 0;
for (var i = 0; i < (message[1] as int); i++) {
sum += i;
}
mainPort.send(['result', sum]);
}
}
});
}
Future<void> main() async {
print('=== 1. 双向通信 + 深拷贝证明 ===');
final receivePort = ReceivePort();
await Isolate.spawn(childIsolate, receivePort.sendPort);
// ReceivePort 是单订阅流,只能 listen 一次:握手与业务消息统一处理
final childPortCompleter = Completer<SendPort>();
final replies = <dynamic>[];
receivePort.listen((message) {
if (message is SendPort) {
childPortCompleter.complete(message); // 1. 握手:拿到子 isolate 的 SendPort
} else {
replies.add(message); // 2. 业务回复
}
});
final childPort = await childPortCompleter.future;
// 传 List:子 isolate 会拿到一份深拷贝副本
final myList = [1, 2, 3, 4];
childPort.send(['echo', myList]);
// 同时发一个计算任务
childPort.send(['compute', 1000000]);
// 等两条回复处理完
await Future.delayed(const Duration(milliseconds: 500));
for (final reply in replies) {
if (reply[0] == 'echo_back') {
print(' 回传数据: ${reply[1]}');
print(' 证明深拷贝: 我主 isolate 的 myList 还是 $myList(未被子 isolate 改动)');
print(' 子 isolate 说明: ${reply[2]}');
} else if (reply[0] == 'result') {
print(' 子 isolate 计算结果: sum(0..999999) = ${reply[1]}');
}
}
// 用 TransferableTypedData 传大数据(零拷贝转移所有权)
print('');
print('=== 2. TransferableTypedData:大数据零拷贝转移 ===');
final bytes = Uint8List.fromList(List.generate(100, (i) => i % 256));
final transferable = TransferableTypedData.fromList([bytes]);
print(' 转移前 buffer 可用: ${bytes.isNotEmpty}');
// transfer 后原 buffer 被 detach;接收端 materialize 取回
final received = transferable.materialize().asUint8List();
print(' 接收端 materialize 拿到 ${received.length} 字节');
print('');
print('=== 3. 结论 ===');
print(' isolate 之间:不共享堆、消息深拷贝(或 TransferableTypedData 转移所有权)');
print(' 数据竞争不存在,代价是传递成本;重计算应整体搬到子 isolate 而非传大数据');
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91