3、Dart:併發程式設計之Isolate

Melrose發表於2019-04-15

   使用Isolate的併發程式設計:與執行緒類似但不共享記憶體的獨立區域,僅通過訊息進行通訊。

Library介紹

  要使用Isolate進行併發程式設計:

  import 'dart:isolate';
複製程式碼

  該Library主要包含下面幾個類:

  1. Isolate:Dart執行上下文的隔離區。
  2. ReceivePort:與SendPort一起,是隔離區之間唯一的通訊方式。
  3. SendPort:將訊息傳送到其他ReceivePort

  所有Dart程式碼都在隔離區中執行,程式碼只能訪問同一個隔離區的類和值。不同的隔離區可以通過埠傳送資訊進行通訊。

  由spawn操作提供的Isolate物件將具有控制隔離所需的控制埠和功能。如有必要,可以使用Isolate.Isolate建構函式建立新的隔離物件,而無需使用這些功能。

建立和啟動Isolate

  要建立Isolate,你可以使用spawn方法。必須為spawn方法提供一個帶有單個引數的“入口點”方法。 通常,此參數列示隔離應用於傳送回通知訊息的埠:

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

main(List<String> args) {

 start();
 
 print("start");

}

Isolate isolate;

int i =1;


void start()async{
 //接收訊息的主Isolate的埠
 final receive = ReceivePort();

  isolate = await Isolate.spawn(runTimer, receive.sendPort);

  receive.listen((data){
    print("Reveive : $data ; i :$i");
  });
}


void runTimer(SendPort port){
 int counter =0 ;
 Timer.periodic(const Duration(seconds: 1), (_){
   counter++;
    i++;
   final msg = "nitification $counter";
   print("Send :$msg ;i :$i");
   port.send(msg);
 });
}
複製程式碼

執行上面的例子控制檯的輸出為:

start
Send :nitification 1 ;i :2
Reveive : nitification 1 ; i :1
Send :nitification 2 ;i :3
Reveive : nitification 2 ; i :1
Send :nitification 3 ;i :4
Reveive : nitification 3 ; i :1
複製程式碼

  在上面的例子中,使用start方法來建立一個埠並生成一個Isolatespawn使用了兩個引數,一個要執行的回撥的函式runTimer,和一個埠(SendPort),回撥可以用來將訊息傳送回撥用者。埠是你與Isolate通訊的方式。這個例子將其設定為單向通行(從隔離區傳送資訊到接收者),但它可以是雙向的。在start方法的最後是監聽來自定義isolate的訊息。

  在控制檯的輸出中可以看出,兩個Isolate中列印的i的值並不一致,則說明Isolate之間的記憶體並不是共享的。

停止Isolate等操作

  在上面的例子中,Isolate可以一直進行下去。如果想Isolate停止執行,可以使用kill方法。

void stop(){
print("kill isolate");
isolate?.kill(priority: Isolate.immediate);
isolate =null;
}
複製程式碼

  上面的程式碼會殺死正在執行的Isolate,並將引用置為nullIsolate.immediate的優先順序將在最近的機會乾淨地關閉Isolate

  還可以暫停和恢復Isolate的執行,分別對應Isolate中的pause方法和resume方法。

相關文章