- Die Zig-Sprache führt ein neues Modell auf Basis der
Io-Schnittstelle ein, um die Komplexität des bisherigen asynchronen I/O-Designs zu reduzieren
- Dieses Modell behält eine einheitliche Funktionsstruktur ohne Unterscheidung zwischen synchronem und asynchronem Code bei und stellt zwei Implementierungen bereit:
Io.Threaded und Io.Evented
Io.Threaded führt standardmäßig synchrone Ausführung aus, während Io.Evented eventbasierte asynchrone Ausführung durchführt
- Entwickler können mit den Funktionen
async() und concurrent() die Parallelausführung steuern; ohne Codeänderung ist eine Leistungsoptimierung möglich
- Dieser Ansatz adressiert das Problem des Function Coloring und zielt darauf ab, Zigs Einfachheit und Kontrollierbarkeit zu bewahren und zugleich asynchrone Leistung sicherzustellen
Änderungen im asynchronen Design von Zig
- Zig hat nach einer neuen Herangehensweise gesucht, da das frühere asynchrone Design nicht gut zur Minimalismus-Philosophie der Sprache passte
- Das alte Design hatte eine niedrige Integration mit anderen Sprachfeatures
- Das neue Modell kann synchrones und asynchrones I/O mit derselben Code-Struktur handhaben
- Das neue Modell ist auf einem generischen
Io-Interface aufgebaut
- Alle I/O-Funktionen führen ihre Ausführung über eine als Parameter übergebene
Io-Instanz aus
- Ähnlich wie bei der
Allocator-Schnittstelle ist es möglich, I/O auf ähnliche Weise wie Speicherzuweisung zu steuern
Struktur des Io-Interfaces
- Die Standardbibliothek enthält zwei Standardimplementierungen
Io.Threaded: standardmäßig synchrone Ausführung, optional parallele Verarbeitung mit Threads
Io.Evented: eventloopbasierte asynchrone Ausführung (unter anderem mit io_uring, kqueue)
- Anwender können eigene neue
Io-Implementierungen schreiben und so die Ausführungsmethode sehr fein steuern
Codebeispiel und Funktionsweise
- Die Beispiel-Funktion
saveFile() erstellt, schreibt und schließt eine Datei
- Mit
Io.Threaded läuft sie über normale Systemaufrufe
- Mit
Io.Evented läuft sie über ein asynchrones Backend
- In beiden Fällen ist die Fertigstellung beim Aufruf von
writeAll() garantiert
- Der gleiche Code arbeitet in synchronen wie asynchronen Umgebungen gleich
- Bibliotheksautor:innen müssen sich nicht um die Ausführungsart kümmern
Parallelausführung mit async() / concurrent()
- Die Funktion
async() fordert eine asynchrone Ausführung an, kann aber bei Io.Threaded sofort ausgeführt werden
- In
Io.Evented erfolgt echte asynchrone Ausführung, sodass beide Dateien parallel gespeichert werden können
- Die Funktion
concurrent() wird verwendet, wenn echte Parallelität nötig ist
Io.Threaded nutzt dabei den Thread-Pool
Io.Evented behandelt sie wie async()
- Eine falsche Funktionsauswahl (
async anstelle von concurrent) gilt als Bug; sie kann sprachlich nicht verhindert werden
Code-Stil und Sprachintegration
- Ohne asynchrone Spezialsyntax bleibt der normale Zig-Code-Stil erhalten
- Bestehende Kontrollflusskonstrukte wie
try und defer werden unverändert verwendet
- Andrew Kelley sagt, dass es sich wie normaler Zig-Code anfühlt
- Als Beispiel wird eine asynchrone DNS-Auflösung gezeigt
- Anders als bei
getaddrinfo() wird nur die erste erfolgreiche Antwort zurückgegeben und die restlichen Anfragen werden abgebrochen
Ausblick und aktueller Stand
Io.Evented befindet sich noch in der experimentellen Phase; einige Betriebssysteme unterstützen es noch nicht
- Eine WebAssembly-kompatible
Io-Implementierung ist geplant und erfordert die Entwicklung entsprechender Features
- Zu
Io gibt es 24 Folgeaufgaben, von denen die meisten noch offen sind
- Zig ist noch vor Version 1.0; asynchrone I/O und native Codegenerierung sind weiterhin die wichtigsten offenen Aufgaben
- Mit diesem Entwurf wird erwartet, dass sich die Notwendigkeit zur Code-Überarbeitung aufgrund von Änderungen an der I/O-Schnittstelle verringert
Zusammenfassung der Community-Diskussion
- Mehrere Kommentare bewerten Zigs Ansatz als einfacher und flexibler als Rusts async/await-Modell
- In Rust ist die Komplexität hoch, wenn mehrere Executor gleichzeitig eingesetzt werden
- Mit dem
Io-Interface eröffnet Zig die Möglichkeit, mehrere Executor parallel zu betreiben
- Einige bemängeln, dass der Code etwas umfangreich werden kann
- Durch das explizite API-Design verbessert sich jedoch die Kontrolle über Sicherheit, Leistung und Tests
- Auch technische Diskussionen über den Unterschied zwischen asynchroner und Thread-Ausführung sowie über stackful vs. stackless Coroutine-Umsetzungen wurden geführt
- Zig
Io ist als Standardbibliotheks-Erweiterung implementiert, ohne Sprach-spezielle Sonderbehandlung
- Künftige Erweiterung um stackless coroutine-Funktionen ist vorgesehen
Fazit
- Das neue asynchrone Modell von Zig zielt darauf ab, sprachliche Einfachheit mit leistungsstarker I/O zu verbinden
- Durch die Lösung des Function-Coloring-Problems, die Integration von synchronem und asynchronem Code und eine explizite Kontrollstruktur wird es als Schlüssel-Schritt zur Stabilisierung von Zig 1.0 bewertet
Noch keine Kommentare.