Les fibres sont un moyen d'implémenter la concurrence de façon collaborative. La classe Fiber
est définie dans le module core.thread
.
L'idée de base est que quand une fibre n'a rien à faire ou qu'elle attend qu'on lui passe des données, elle le signale explicitement en appelant Fiber.yield()
. Le contexte parent reprend alors le contrôle de l'exécution, mais l'état de la fibre, et de toutes ses variables est sauvegardé et continuera après l'appel à Fiber.yield()
. Magique ? Oui.
void foo()
{
writeln("Bonjour");
Fiber.yield();
writeln("Tout le monde");
}
//...
auto f = new Fiber(&foo);
f.call(); // affiche Bonjour
f.call(); // affiche Tout le monde
Cette fonctionnalité peut être utilisée pour implémenter de la concurrence où plusieurs fibres collaborent sur un seul coeur. L'avantage des fibres comparées aux threads est qu'elles consomment moins de ressources, puisqu'il n'y a pas besoin de passer d'un contexte à un autre.
Un très bon usage de cette technique peut être vu dans la bibliothèque vibe.d qui implémente des opérations d'E/S asynchrones avec des fibres, ce qui rend le code très propre.