openlang

isolate 都结束了,对 ReceivePort 的 await for 却一直不结束

大家好,我写了个小的 dart 工具,用来汇总温度 CSV,每个文件起一个 isolate,这样大文件不用互相等。我在 WSL 里这样跑

dart run bin/summarize.dart data/north.csv data/south.csv -v

加了 -v 能看到两行 "spawned worker",然后是两行 "got ... rows",行数也是对的。所以 worker 显然把活干完了。但是之后就没动静了。没有表格,也不回到提示符,只能 Ctrl+C。

一开始我以为是 worker 里的 readAsLinesSync 阻塞了什么,后来把 worker 主体包了 try/catch,但什么都没抛,也没有变化。

让我困惑的是,我记得 main 里的循环会在所有 spawn 出去的 isolate 都结束后自己结束。所以我才用 await for,没有去数结果。主要部分是这样的。

final port = ReceivePort();

for (final p in paths) {
  await Isolate.spawn(summarizeFile, WorkOrder(p, port.sendPort));
  log.debug('spawned worker for $p');
}

final results = <FileSummary>[];
await for (final msg in port) {
  final s = msg as FileSummary;
  results.add(s);
  log.info('got ${s.path}: ${s.count} rows');
}

results.sort((a, b) => a.path.compareTo(b.path));
printTable(results);

worker 最后就是 order.replyTo.send(FileSummary(...)) 然后返回。最近的 Dart 3.x。循环结束的时机有变过吗?在搞懂这个之前,我不想重写收集结果的部分。

从英语翻译查看原文

后续讨论 2

顺着彼此的依据读下去

同一个问题的其他角度

  1. 已取消 context 但出错后 worker goroutine 仍然存活(总是 workers + 2)

    大家好, 我在写一个小型 Go CLI,叫 shotcheck,用来检查文件夹里每张 PNG 是否符合 App Store 对应位置要求的精确尺寸。一个 worker 池(默认 8 个)从 jobs 里读文件名,检查后把 Result 发到无缓冲的…

    回复 4最近活动 go
  2. 把过滤函数标成 async,卡顿一点没变

    ledgerscan 在 400k 条记录上做搜索。我把 run 改成了 async,在 main 里 await 它,本以为 100 ms 的心跳 Timer 会一直跳。结果先是几下 tick,然后打出 searching "rent"...,接着…

    回复 2最近活动 dart
  3. outliers.log 的行数比 :outliers 计数多,8 个 future

    我用 8 个 future 把 20000 条模拟潮汐读数折叠进同一个 atom。每条超过阈值的读数还会被追加到 outliers.log。汇总结果没问题,:n 始终是 20000,:outliers 每次运行都一样,因为种子是固定的。但日志的行数比…

    回复 1最近活动 clojure