在dart中等待分离株的策略

ldioqlga  于 2023-04-27  发布在  其他
关注(0)|答案(2)|浏览(131)

我有一段代码,它生成了x个Isolate,这些isolates都在运行http服务器。(true)block如下所示,带有async await,这样CPU就不会疯狂运行。我完全忘记了它,直到几个月后审查代码时。这似乎是不必要的,虽然我可以为所有分离株添加一个终止开关,但这回避了问题;在退出之前,我该如何等待分离菌株死亡呢?现在,while循环使整个应用程序保持活动状态。

main() async {
  Server http_server = Server(80, 3);
  http_server.start();

  while(true) {
    await Future.delayed(Duration(seconds: 1));
  }
}
g52tjvyc

g52tjvyc1#

我会使用其他分离菌株的onExit处理程序来报告它们何时死亡,然后在主分离菌株中侦听。
所以:

var exitPort = RawReceivePort();
var liveIsolates = 0;
// Don't close port while still creating new isolates.
var isInitializing = true;
exitPort.handler = (_) {
  if (--liveIsolates == 0 && !isInitializing) exitPort.close();
};

try {
  for (var i = 0; i < x; i++) {
    liveIsolates++;
    ... Isolate.spawn(...., onExit: exitPort.sendPort) ...
  }
} finally {
  isInitializing = false;
  if (liveIsolates == 0) {
    // All isolate terminated already (or `x` was zero).
    exitPort.close();
  }
}

这将在每个派生的isolate退出时向exitPort发送(null)消息。当它们全部完成时,主isolate关闭其最后一个接收端口,并且也可以关闭。

2admgd59

2admgd592#

您应该创建一个ReceivePort,然后将此示例作为参数发送到您的Isolate示例(根据所需的细节量,为每个Isolate创建一个ReceivePort或重复使用相同的ReceivePort)。通过这样做,您可以将数据发送回主隔离菌株,并且主隔离菌株不会停止,因为它有一个打开的ReceivePort,可以防止隔离菌株停止。
例如,您可以设置它,以便HTTP服务器可以要求关闭整个服务器。或者,您可以只保持ReceivePort示例打开,这将防止主隔离停止,而无需忙碌着等待(在这种情况下,您不需要将SendPort示例发送到隔离中。Dart不会跟踪ReceivePort何时应该关闭,所以你必须手动关闭它,当你认为它已经完成)。
示例:

import 'dart:async';
import 'dart:isolate';

void main() {
  ReceivePort receivePort = ReceivePort();
  receivePort.listen((message) {
    print('Got: $message');

    if (message == 'Goodbye') {
      print('Close ReceivePort and therefore also the program since '
          'nothing else are running that could trigger an event.');
      receivePort.close();
    }
  });

  Isolate.spawn(myIsolate, receivePort.sendPort);
}

void myIsolate(SendPort msg) {
  print('Running inside isolate. Wait 5 seconds before sending message back');
  Timer(const Duration(seconds: 5), () => msg.send('Goodbye'));
}

相关问题