Introducció
En Dart, els isolates són una manera de gestionar la concurrència. A diferència dels fils (threads) en altres llenguatges de programació, els isolates no comparteixen memòria. Cada isolate té el seu propi espai de memòria i comunicació amb altres isolates a través de missatges. Això fa que la programació concurrent sigui més segura i menys propensa a errors com les condicions de carrera.
Conceptes Clau
- Isolate: Un procés lleuger amb el seu propi espai de memòria.
- Port: Un canal de comunicació entre isolates.
- SendPort: Un port que permet enviar missatges a un altre isolate.
- ReceivePort: Un port que permet rebre missatges d'altres isolates.
Creació d'un Isolate
Per crear un isolate, utilitzem la funció Isolate.spawn
. Aquesta funció pren com a arguments una funció i un missatge inicial que es passa a aquesta funció.
Exemple
import 'dart:isolate'; void isolateFunction(SendPort sendPort) { // Enviar un missatge de tornada al port principal sendPort.send('Hola des de l\'isolate!'); } void main() async { // Crear un port de recepció ReceivePort receivePort = ReceivePort(); // Crear un isolate await Isolate.spawn(isolateFunction, receivePort.sendPort); // Escoltar els missatges de l'isolate receivePort.listen((message) { print('Missatge rebut: $message'); receivePort.close(); // Tancar el port després de rebre el missatge }); }
Explicació del Codi
- Importació del Mòdul: Importem el mòdul
dart:isolate
per utilitzar les funcionalitats d'isolate. - Funció de l'Isolate: Definim una funció
isolateFunction
que rep unSendPort
com a argument i envia un missatge a aquest port. - Port de Recepció: Creem un
ReceivePort
en elmain
per rebre missatges de l'isolate. - Creació de l'Isolate: Utilitzem
Isolate.spawn
per crear un nou isolate i passar-li elSendPort
delReceivePort
. - Escolta de Missatges: Utilitzem
receivePort.listen
per escoltar els missatges que arriben alReceivePort
i imprimir-los.
Comunicació entre Isolates
La comunicació entre isolates es fa mitjançant l'enviament de missatges a través de ports. Els missatges poden ser de qualsevol tipus que es pugui serialitzar, com ara cadenes, nombres, llistes i mapes.
Exemple Avançat
import 'dart:isolate'; void isolateFunction(SendPort sendPort) { // Crear un port de recepció dins de l'isolate ReceivePort isolateReceivePort = ReceivePort(); // Enviar el port de recepció de l'isolate al port principal sendPort.send(isolateReceivePort.sendPort); // Escoltar els missatges del port de recepció de l'isolate isolateReceivePort.listen((message) { print('Missatge rebut a l\'isolate: $message'); isolateReceivePort.close(); // Tancar el port després de rebre el missatge }); } void main() async { // Crear un port de recepció ReceivePort receivePort = ReceivePort(); // Crear un isolate await Isolate.spawn(isolateFunction, receivePort.sendPort); // Obtenir el port de recepció de l'isolate SendPort isolateSendPort = await receivePort.first; // Enviar un missatge a l'isolate isolateSendPort.send('Hola des del port principal!'); // Tancar el port principal receivePort.close(); }
Explicació del Codi
- Port de Recepció dins de l'Isolate: Creem un
ReceivePort
dins de l'isolate per rebre missatges. - Enviament del Port de Recepció: Enviem el
SendPort
delReceivePort
de l'isolate al port principal. - Escolta de Missatges dins de l'Isolate: Utilitzem
isolateReceivePort.listen
per escoltar els missatges que arriben alReceivePort
de l'isolate. - Enviament de Missatges des del Port Principal: Utilitzem el
SendPort
de l'isolate per enviar un missatge des del port principal.
Exercicis Pràctics
Exercici 1: Comunicació Bàsica
Crea un programa que utilitzi un isolate per calcular la suma de dos nombres i enviar el resultat al port principal.
Solució
import 'dart:isolate'; void sumFunction(List<dynamic> args) { int a = args[0]; int b = args[1]; SendPort sendPort = args[2]; int sum = a + b; sendPort.send(sum); } void main() async { ReceivePort receivePort = ReceivePort(); await Isolate.spawn(sumFunction, [5, 10, receivePort.sendPort]); int result = await receivePort.first; print('La suma és: $result'); receivePort.close(); }
Exercici 2: Comunicació Bidireccional
Crea un programa on el port principal envia una llista de nombres a l'isolate, i l'isolate retorna la llista amb cada nombre multiplicat per 2.
Solució
import 'dart:isolate'; void doubleListFunction(SendPort sendPort) { ReceivePort isolateReceivePort = ReceivePort(); sendPort.send(isolateReceivePort.sendPort); isolateReceivePort.listen((message) { List<int> numbers = message; List<int> doubledNumbers = numbers.map((n) => n * 2).toList(); sendPort.send(doubledNumbers); isolateReceivePort.close(); }); } void main() async { ReceivePort receivePort = ReceivePort(); await Isolate.spawn(doubleListFunction, receivePort.sendPort); SendPort isolateSendPort = await receivePort.first; List<int> numbers = [1, 2, 3, 4, 5]; isolateSendPort.send(numbers); List<int> result = await receivePort.first; print('Llista multiplicada per 2: $result'); receivePort.close(); }
Errors Comuns i Consells
- No tancar els ports: Assegura't de tancar els ports de recepció (
ReceivePort
) després d'usar-los per evitar fuites de memòria. - Enviar objectes no serialitzables: Només envia objectes que es puguin serialitzar entre isolates.
- No gestionar errors: Utilitza blocs
try-catch
per gestionar errors dins de les funcions dels isolates.
Conclusió
Els isolates són una eina poderosa per gestionar la concurrència en Dart. Permeten executar codi en paral·lel de manera segura, sense els problemes associats amb la memòria compartida. Amb la pràctica, podràs utilitzar els isolates per crear aplicacions més eficients i responsives.
Curs de Programació en Dart
Mòdul 1: Introducció a Dart
- Introducció a Dart
- Configuració de l'Entorn de Desenvolupament
- El Teu Primer Programa en Dart
- Sintaxi i Estructura Bàsica
Mòdul 2: Conceptes Bàsics de Dart
Mòdul 3: Col·leccions
Mòdul 4: Programació Orientada a Objectes en Dart
Mòdul 5: Funcionalitats Avançades de Dart
Mòdul 6: Gestió d'Errors i Depuració
Mòdul 7: Paquets i Biblioteques de Dart
Mòdul 8: Dart per a Web i Mòbil
- Introducció a Flutter
- Construcció d'una Aplicació Simple amb Flutter
- Dart per al Desenvolupament Web