21

我可能对孤立和未来有错误的想法。请帮我清理一下。这是我对这两个主题的理解。

隔离:在自己的事件循环中隔离运行代码,每个事件都可以在嵌套的微任务队列中运行较小的任务。

Future:Future 用于表示将来某个时间可用的潜在值或错误。

我的困惑是:

  1. 医生说 Isolate 有它自己的循环?我觉得拥有自己的事件队列对我来说更有意义,我错了吗?

  2. 未来是否在主 Isolate 上异步运行?我假设未来的任务实际上被放置在事件队列的末尾,所以如果它将来会被循环执行。如我错了请纠正我。

  3. 为什么在有未来时使用 Isolate?我看到了一些使用 Isolate 代替 Future 来完成繁重任务的示例。但为什么?只有当将来在主隔离队列上异步执行时,它才对我有意义。

4

4 回答 4

19

AFuture是一个句柄,允许您在异步执行完成时收到通知。异步执行使用事件队列,代码在同一个线程中并发执行。

https://webdev.dartlang.org/articles/performance/event-loop

Dart 代码默认在根隔离中执行。

您可以启动通常在另一个线程上运行的其他隔离。隔离可以从与根隔离开始的相同 Dart 代码加载(使用与main() https://api.dartlang.org/stable/2.0.0/dart-isolate/Isolate/spawn.html不同的入口点) 或使用不同的 Dart 代码(从某个 Dart 文件或 URL https://api.dartlang.org/stable/2.0.0/dart-isolate/Isolate/spawnUri.html加载)。

隔离不共享任何状态,只能使用消息传递(SendPort/ReceivePort)进行通信。每个隔离都有自己的事件队列。

https://webdev.dartlang.org/articles/performance/event-loop

于 2018-09-25T13:03:58.723 回答
10

Isolate 在单个线程上运行 Dart 代码。同步代码如

print('hello');

立即运行,不能中断。

Isolate 还有一个事件循环,用于安排异步任务。异步并不意味着这些任务在单独的线程上运行。它们仍然在同一个线程上运行。异步只是意味着它们被安排在以后。

事件循环运行在所谓的事件队列中安排的任务。您可以通过创建这样的未来将任务放入事件队列中:

Future(() => print(hello));

当事件队列中前面的其他任务完成时,该print(hello)任务将运行。所有这些都发生在同一个线程上,即同一个 Isolate。

例如,某些任务不会立即添加到事件队列中

Future.delayed(Duration(seconds: 1), () => print('hello'));

仅在延迟一秒后才添加到队列中。

到目前为止,我一直在谈论的一切都是在同一个线程上完成的,同一个 Isolate。不过,有些工作实际上可能在不同的线程上完成,例如 IO 操作。底层框架负责这一点。如果在主 Isolate 线程上完成了诸如从磁盘读取之类的昂贵操作,那么它将阻塞应用程序直到它完成。当 IO 操作完成时,future 完成并将结果更新添加到事件队列中。

当您需要自己执行 CPU 密集型操作时,您应该在另一个隔离区上运行它们,以免在您的应用程序中造成卡顿。计算属性对此很有用。您仍然使用未来,但这次未来是从不同的隔离返回结果。

进一步研究

于 2020-06-06T09:52:59.110 回答
9

我们可以用一句话说,

Isolates:Dart 是单线程的,但它能够使用 Isolates(许多进程)进行多线程处理。

Future:Future 是 dart 完成异步工作时返回的结果。这项工作通常在那个单线程中完成。

于 2018-09-25T18:13:59.130 回答
3

即使 dart 不是多线程的,也可以将 Isolate 与 Thread 进行比较。当 Futures 共享相同的内存时,它确实有自己的内存和事件循环

Dart 能够产生独立的进程,称为 Isolates(dart2js 中的网络工作者),当主程序时它们不共享内存,但能够异步地在另一个进程(实际上是一个线程)中进行计算而不会阻塞主线程。

Future 在调用它的 Isolate 中运行,而不是在主隔离中运行。

我推荐这篇比我有更好解释的文章。

于 2018-09-25T13:06:37.497 回答