4 points par GN⁺ 2025-12-04 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Le langage Zig introduit un nouveau modèle basé sur l’interface Io pour réduire la complexité du design asynchrone d’I/O existant
  • Ce modèle conserve une structure de fonction identique sans distinguer code synchrone et asynchrone, et propose deux implémentations : Io.Threaded et Io.Evented
  • Io.Threaded exécute par défaut de manière synchrone, tandis que Io.Evented exécute en mode asynchrone basé sur une boucle d’événements
  • Les développeurs peuvent contrôler l’exécution parallèle via async() et concurrent(), avec une optimisation des performances possible sans modifier le code
  • Cette approche résout le problème de la coloration de fonctions et vise à préserver la simplicité et le contrôle de Zig tout en offrant de hautes performances asynchrones

Évolution de la conception asynchrone de Zig

  • Zig, estimant que l’ancien modèle asynchrone ne s’accordait pas bien avec sa philosophie de minimalisme, a recherché une nouvelle approche
    • L’ancien modèle avait une faible intégration avec le reste des fonctionnalités
    • Le nouveau modèle permet de gérer l’I/O synchrone et asynchrone avec la même structure de code
  • Le nouveau modèle est centré sur une interface générique Io
    • Toutes les fonctions d’I/O reçoivent une instance Io en paramètre pour s’exécuter
    • À l’image de l’interface Allocator, il permet de piloter l’I/O de la même manière que l’allocation mémoire

Structure de l’interface Io

  • La bibliothèque standard inclut deux implémentations de base
    • Io.Threaded : exécution synchrone par défaut, avec traitement parallèle par threads si nécessaire
    • Io.Evented : exécution asynchrone basée sur une boucle d’événements (io_uring, kqueue, etc.)
  • Les utilisateurs peuvent écrire de nouvelles implémentations Io, pour un contrôle fin du mode d’exécution

Exemple de code et fonctionnement

  • La fonction d’exemple saveFile() crée, écrit et ferme un fichier
    • Avec Io.Threaded, elle s’exécute avec des appels système classiques
    • Avec Io.Evented, elle s’exécute via un backend asynchrone
    • Dans les deux cas, writeAll() garantit que l’opération est terminée au moment de son appel
  • Le même code fonctionne de la même manière dans les contextes synchrone et asynchrone
    • Les auteurs de bibliothèques n’ont pas à se soucier du mode d’exécution

Exécution parallèle et async() / concurrent()

  • La fonction async() demande une exécution asynchrone, mais avec Io.Threaded, elle peut s’exécuter immédiatement
    • Avec Io.Evented, il est possible de sauvegarder deux fichiers en parallèle avec une exécution réellement asynchrone
  • La fonction concurrent() est utilisée lorsque une exécution réellement parallèle est nécessaire
    • Io.Threaded utilise un pool de threads
    • Io.Evented fonctionne de la même manière que async()
  • Un mauvais choix de fonction (async au lieu de concurrent) est considéré comme un bug et ne peut pas être empêché au niveau du langage

Style de code et intégration au langage

  • Sans syntaxe dédiée à l’asynchrone, le style de code Zig standard est conservé
    • Les structures de contrôle existantes comme try, defer sont utilisées telles quelles
    • Andrew Kelley a indiqué que « cela se lit comme du code Zig standard »
  • Un exemple de résolution DNS asynchrone est présenté
    • Contrairement à getaddrinfo(), il ne renvoie que la première réponse réussie et annule les autres requêtes

Planification future et état d’avancement

  • Io.Evented est encore en phase expérimentale, avec un support incomplet sur certains systèmes d’exploitation
  • Une implémentation Io compatible WebAssembly est prévue, et un travail fonctionnel correspondant reste à effectuer
  • Il existe 24 tâches de suivi liées à Io, dont la majorité sont encore incomplètes
  • Zig n’étant pas encore en version 1.0, l’I/O asynchrone et la génération de code natif restent des chantiers majeurs
  • Ce modèle devrait permettre de réduire la fréquence de réécriture du code causée par des changements dans l’interface I/O

Synthèse des discussions communautaires

  • Plusieurs commentaires jugent l’approche de Zig plus simple et plus flexible que le modèle async/await de Rust
    • Rust devient plus complexe en combinant plusieurs executors
    • Zig permet la coexistence de plusieurs executors grâce à l’interface Io
  • Certains soulignent que le code peut devenir un peu verbeux
    • Mais une API explicite améliore la sécurité, les performances et le contrôle des tests
  • Les discussions techniques ont aussi abordé la différence entre exécution asynchrone et exécution thread, ainsi que les implémentations de coroutines stackful et stackless
  • L’Io de Zig est implémenté sous forme d’extension de la bibliothèque standard, sans traitement spécial au niveau du langage
    • Une implémentation de coroutine stackless est prévue à l’avenir

Conclusion

  • Le nouveau modèle asynchrone de Zig vise à concilier la simplicité du langage et les performances I/O élevées
  • En résolvant le problème de la coloration de fonctions, en intégrant code synchrone et asynchrone, et grâce à une structure de contrôle explicite, il est considéré comme une étape clé vers la stabilisation de Zig 1.0

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.