Dart Isolates

 

Dart Isolates

Dart allows us to asynchronous programming which runs our program without getting blocked. The asynchronous programming is used to achieve concurrency. Dart isolate is a version of the thread. But there is key difference between the common implementation of "Thread" or "Isolates". The isolate works differently in comparison of Thread. The isolates are independent workers that do not share memory, but instead interconnect by passing message over channels. Since isolates completes its task by passing message thus it need a way to serialize a message.

The communication between the isolates is done by the message passing as a client and server. It helps the program to take advantage of multicore microprocessor out of the box.

Dart provides the dart:isolate package to apply the isolate in our program. It provides the solution to taking single-threaded Dart code and allowing application to make greater use of the hardware available.

Create and Start an Isolate

Dart provides the spawn() method to create an isolate. It must be declared with an 'entry point' with a single parameter. This parameter displays a port which isolate use to refer back notification message.

Let's understand the following example -

Example -

  1. import 'dart:isolate';    
  2. void sayhii(var msg){   
  3.    print('execution from sayhii ... the message is :${msg}');   
  4. }    
  5. void main(){   
  6.    Isolate.spawn(sayhii,'Hello!!');   
  7.    Isolate.spawn(sayhii,'Whats up!!');   
  8.    Isolate.spawn(sayhii,'Welcome!!');   
  9.      
  10.    print('execution from main1');   
  11.    print('execution from main2');   
  12.    print('execution from main3');   
  13. }  

Output:

execution from main1
execution from main2
execution from main3
execution from sayhii ... the message is :Whats up!!
execution from sayhii ... the message is :Hello!!

Output 2:

execution from main1
execution from main2
execution from main3
execution from sayhii ... the message is :Hello!!
execution from sayhii ... the message is :Welcome!!

Explanation:

In the above program, the spawn method of the isolate class executed a function sayhii in parallel of remaining code. It takes two parameters.

  • The function that we want to spawned and the string that will be passed to the spawned function.

We have two functions sayhii() and main() function might not run in the same order each time. If you run the above program, then the output will be different each time as we can see in second output.

Note - We can also pass NULL value if there is no object to pass in spawned function.

Let's understand the another example -

Example - 2

  1. void start() async {  
  2.          ReceivePort  receiverPort = ReceiverPort();   // Port for isolate to receive message.  
  3.          isolate = await Isolate.spawn(runTimer, receiverPort.sendPort);  
  4.          receivePort.listen((data){  
  5.                stdout.write('Receiving: '+ data + ', ');  
  6.   
  7.      });  
  8.   
  9. }  
  10. void runTimer(SendPort, sendPort) {  
  11. int coun = 0;  
  12. Timer.periodic(new Duration(seconds: 1), (Timer t) {  
  13.      count++;  
  14.      String msg = 'notification ' + count.toString();  
  15.      stdout.write('Sending: ' + msg + ' -');  
  16.      sendPort.send(msg);  
  17.   
  18. });  
  19. }  

Explanation:

In the above code, we created an asynchronous method start() which creates a port and spawn an isolate. We signified the start method as async because of wan can await the response from the spawning of the isolates and to store a reference to the new isolate. It is essential when we want to kill the running isolates. We passed the two parameters in the spawn() method, the first parameter runTimer method, that is a callback function to execute runTimer() and second parameter sendPort which is a callback function and it will used to send message back to the caller. The start() method starts listening the receiverPort for message from isolate. Once it will receive the message then it will print as a console output.

The runTimer() method begins a timer that fires every second in order to update a counter. It sends a notification message via the port which it received when the isolate was spawned.

Stop an Isolate

The dart: isolates package provides the kill() method which is used to stop a running isolate.

Let's understand the following example.

Example -

  1. void stop() {    
  2.         If (isolate != null) {  
  3.         stdout.writeln('Stopping Isolate');  
  4.         isolate.kill(priority: Isolate.immediate);  
  5.         isolate = null;  
  6.         }  
  7. }  

Explanation:

In the above example, we have declared a stop() method that will destroy the running isolate and sets its reference to null. We defined the priority of isolate: immediate that will terminate the isolate as soon as.

Complete Program

  1. import 'dart:io';  
  2. import 'dart:async';  
  3. import 'dart:isolate';  
  4.   
  5. Isolate isolate;  
  6.   
  7. // Start the isolate   
  8. void start() async {  
  9.          ReceivePort  receiverPort = ReceiverPort();   // Port for isolate to receive message.  
  10.          isolate = await Isolate.spawn(runTimer, receiverPort.sendPort);  
  11.          receivePort.listen((data){  
  12.                stdout.write('Receiving: '+ data + ', ');  
  13.   
  14.      });  
  15.   
  16. }  
  17. void runTimer(SendPort, sendPort) {  
  18. int coun = 0;  
  19. Timer.periodic(new Duration(seconds: 1), (Timer t) {  
  20.      count++;  
  21.      String msg = 'notification ' + count.toString();  
  22.      stdout.write('Sending: ' + msg + ' -');  
  23.      sendPort.send(msg);  
  24.   
  25. });  
  26. }  
  27.   
  28. // Stopping the isolate using the stop() function.  
  29. void stop() {  
  30.     if (isolate != null) {  
  31.           stdout.writeln('Stopping Isolate.....');  
  32.           isolate.kill(priority:Isolate.immediate);  
  33.           isolate = null;   
  34.      }  
  35. }  
  36.   
  37. void main() async {  
  38.     stdout.writeln('Starting Isolate...');  
  39.     await start();  
  40.     std.writeln('Hit enter key to quit');  
  41.     await stdin.first;  
  42.     stop();  
  43.     stdout.writeln('Bye!');  
  44.     exit(0);  
  45. }  

Output:

Stating Isolate 
Hit enter key to quit 
Sending: notification 1 - Receiving: notification 1, Sending: notification 2 - Receiving: notification 2,
Stopping Isolate

Comments