【问题标题】:Will Dart execute isolates in parallel in a multi-core environment?Dart 会在多核环境中并行执行隔离吗?
【发布时间】:2012-07-06 13:59:25
【问题描述】:

问题

Dart 中的隔离会在多核环境中利用所有可用内核并行运行,还是会在单核上多路复用?

背景

Google 将 Dart 编程语言中的 isolates(单线程并发单元)描述为在主堆栈上运行的“轻量级线程”,没有阻塞。

因此,在我看来,它只能在单核上多路复用,而不能在 SMP、双核、多核或集群环境中的多个核上并行运行。

不过,我找不到任何关于此的信息,因此我提出了一个谦虚的问题。

【问题讨论】:

  • 您是否进行了任何实验来解决这个问题?
  • 它没有自己的堆栈,它不是线程。更像协程,也许吧?如果“线程”不能阻塞,它就不能等待 I/O 或其他线程。我看不出这样的装置有什么好处
  • 是的,确实不是线程。我刚刚完成了一些测试(在我问这个问题之前我不运行它们是愚蠢的)。

标签: multithreading parallel-processing dart dart-isolates


【解决方案1】:

警告:以下代码已过期,不适用于 Dart 1.0。

简答

也许吧。

长答案

dart:isolate library guide 声明:“隔离可能在单独的进程或线程中运行,具体取决于实现。对于 Web 应用程序,隔离可以编译为 Web 工作者,如果它们是可用。”(我的重点)

运行此代码并观察您的 CPU 负载将告诉您您的实现是否这样做。

#import('dart:isolate');
main() {
  for (var tmp = 0; tmp < 5; ++tmp) {
    SendPort sendPort = spawnFunction(runInIsolate);
    sendPort.call(tmp).then((reply) {
      print(reply);
    });
  }
}

runInIsolate() {
  port.receive((msg, SendPort reply) {
    var k = 0;
    var max = (5 - msg) * 100000000; 
    for (var i = 0; i < max; ++i) {
        i = ++i - 1;
        k = i;
    }
    reply.send("I received: $msg and calculated $k");
  });
}

独立的 dartvm 并行运行隔离,利用所有可用的内核。 Dart 的浏览器实现可能会有所不同,具体取决于是否实现了 Web Worker。

【讨论】:

    【解决方案2】:

    这里是 Dart 1.0 的更新代码。

    import 'dart:isolate';
    
    main() {
      int counter = 0;
    
      ReceivePort receivePort = new ReceivePort();
    
      receivePort.listen((msg) {
        if (msg is SendPort) {
          msg.send(counter++);
        } else {
          print(msg);
        }
      });
    
      for (var i = 0; i < 5; i++) {
        Isolate.spawn(runInIsolate, receivePort.sendPort);
      }
    }
    
    runInIsolate(SendPort sendPort) {
      ReceivePort receivePort = new ReceivePort();
      sendPort.send(receivePort.sendPort);
    
      receivePort.listen((msg) {
        var k = 0;
        var max = (5 - msg) * 100000000; 
        for (var i = 0; i < max; ++i) {
            i = ++i - 1;
            k = i;
        }
        sendPort.send("I received: $msg and calculated $k");
      });
    }
    

    【讨论】:

    • Dartvm 是否并行运行隔离?它能够使用所有可用的内核吗?
    【解决方案3】:

    我查了一下。隔离似乎是实际的线程。

    隔离之间唯一可用的通信机制是传递消息。

    很好,除了

    每个隔离区都有自己的堆,这意味着内存中的所有值(包括全局值)仅可用于该隔离区。

    一点都不好,因为消息:

    也可以发送对象实例(将在进程中复制

    非常糟糕。

    这种方案似乎无法在不复制的情况下将大量数据从一个隔离区传递到另一个隔离区,因此消除了高效的interisolate通信。

    我不会使用它,因为这种限制不允许按地址传递大型对象/缓冲区,就像通常使用传统线程所做的那样。

    起初看起来很有趣,因为我几乎只使用消息传递设计,但他们坚持只使用私有堆来破坏线程间通信。

    【讨论】:

    • 库文档指出:“隔离可能在单独的进程或线程中运行,具体取决于实现。对于 Web 应用程序,隔离可以编译为 Web 工作者,如果他们有空。” (我的重点)
    • 我不会那么担心这个。 Dart 的人肯定意识到了这个问题,因为是 Google Chrome 率先提出了 Web Worker 之间对象可转移的概念(参见updates.html5rocks.com/2011/12/…)。我希望这样的东西也会出现在 Dart 中。
    • 这不是一个错误,而是一种防止一个线程通过 ref 更改其他线程中使用的任何内容的功能。 Rust 故意以同样的方式做这件事。 D 没有为每个线程提供单独的堆,但是您不能通过引用 D 中的线程来发送任何内容。
    • 我认为这是因为GC是单线程的,并且只针对一个Isolate。所以Isolate之间无法共享对象。 V8 具有类似的设计和限制。
    • 隔离基本上是 Web Workers,但对于 Dart?正在考虑从 nodejs 切换到 dart 服务器,但是……如果 V8 是单线程的……我仍然需要将对象传递给其他隔离或 Web 工作者,对吗?
    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 2012-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    • 1970-01-01
    相关资源
    最近更新 更多