Here we are again with another topic about Dart language, first of all I’d like to start this article with an off-topic.
I joined to FluentJS in San Francisco few weeks ago, an event organize by O’Reilly focus on Javascript development, and I saw a Dart language session, the most amazing thing I’ve seen was the passion behind this project, trust me that it’s not easy today find people that believe in that way in something, Seth Ladd, the speaker and team member of Dart, gave us a great technical introduction to Dart but gave us something more, he transmitted us all his passion on Dart, really amazing!
After this quick off-topic, let’s go ahead with Isolates tutorial.
First of all, Isolates is the Dart way to work with threads and allow to take advantage of your multicore computer, but what is multithreading and when we should use it.
Multithreading
This is a good definition for me: “Multithreading is the ability of a CPU to execute several threads of execution apparently at the same time. CPUs are very fast at executing instructions. Modern PCs can execute nearly a billion instructions every second. Instead of running the same program for one second, the CPU will run one program for perhaps a few hundred microseconds then switch to another and run it for a short while and so on.” (source: cplus.about.com)
And when should we use threads?!
Basically every time you need to speed up an intensive process, for example when you have an heavy process like unzip of a big file or a for cycle with a lots of elements, you should use the threads to don’t freeze the main one and allow your user to work the interface without any issues.
Dart adds this capability in 2 different ways because, as you know you, it can export a project for Dart VM or in Javascript, with Dartium we can use the power of CPUs of your multicore computer and create different threads in each CPU where will be executed your code, in Javascript, Dart converts Isolates in web workers.
Before starting with code I decide to show in a chart how we’ll work with isolates, so basically first of all we create 2 isolates launched from the main isolate and then we pass the final informations elaborated in different isolates to the main one.
Last note, when you work with isolate you can have a sender and a receiver, so in the main isolate (launched by the application) you have a port object where you can listen when you receive informations from other isolates and you can pass the sendport object where you can send message to other isolates.
port.receive((data, SendPort replyTo){ replyTo.send("something"); });
Another important thing to remember when you work with isolates, if you need to receive messages from other isolates, is that you always set the receiver in the main isolate, or you will n0t receive any message from other isolates because the execution of your program is not waiting for any reply without a receiver set.
I created a small project around this topic to show the powerful of the isolates, take a look here:
As you can see when I click on MONO link my CSS animation stops until to the heavy iteration is finished instead when I click on ISOLATE link everything works well because all the iterations are accomplished in different isolates so the main one could go ahead with own job.
When you want to launch an isolate you have to call the spawnfunction method and pass the main isolate sender:
var isolate = spawnFunction(bigForCycle); isolate.send("data", port.toSendPort());
After that you can operate with your isolate in this way for example:
void bigForCycle(){ port.receive((data, SendPort replyTo){ var count; for(var i = 0; i < FINAL_AMOUNT; i++){ count = i; } replyTo.send(count); }); }
It’s finally important remember to close isolates after received the message so when they have finished to accomplish own function, to do that you have only to call the close method in the main isolate and it will not receive any other information from other isolates.
In my example I launched 2 isolates to accomplish the task, so I created a counter variables to store how many reply the main isolate received, after received all replies I can close the communication with other isolates:
port.receive((data, SendPort replyTo){ counterIsolate++; end = new DateTime.now(); if(counterIsolate == 2){ var finalTime = end.difference(start).toString(); myH1.appendHtml("isolate total time: <b>$finalTime</b><br/>"); // if you want to close isolates you have to use the line below port.close(); } });
The most interesting thing is that you can accomplish the same task in 2 different way, the first one, as I did in my example, with inline isolates and the second one is loading code dinamically from external Dart files.
To take a look to the second one I suggest to read this post made by Seth Ladd.
Isolate technique is very useful also when you are working on a serverside project with Dart because it could optimize some intensive process that you have to achieve during your project.
I’ve just opened a github repository with all Dart examples that I’m working on, so feel free to check out at this link.
Enjoy!