Rust'taki asenkronluk, gelecekte sonuçlanacak bir işi temsil eden Future nesnesi aracılığıyla gerçekleştirilir. async fn ile tanımlanan fonksiyonlar, Future trait'ini uygulayan anonim bir yapı-jeneratörü döner. Asenkron kodu çalıştırmak için bir runtime (örneğin, Tokio veya async-std) kullanılır, çünkü standart kütüphane yerleşik bir event loop içermez.
Rust'ın ana özellikleri:
Örnek:
use tokio::time::sleep; use std::time::Duration; async fn foo() { println!("Merhaba"); sleep(Duration::from_secs(1)).await; println!("Dünya!"); } #[tokio::main] async fn main() { foo().await; }
Rust'ta asenkron bir fonksiyon varsayılan olarak çağrıldığında hemen çalışabilir mi? Neden?
Cevap:
Hayır. async fn çağrısı, bir sonuç değil, bir Future (durum makinesi) türünde nesne döner. Gerçek bir yürütme için .await çağrılmalı veya Future bir runtime'a verilmelidir. Çağrı yalnızca görevin tanımını oluşturur, ancak onu yürütmez.
Örnek:
async fn answer() -> u32 { 42 } let fut = answer(); // burada bir yürütme yok, sadece future oluşturuluyor let result = fut.await; // yürütme burada başlıyor
Hikaye
.await çağrısı yapmadı. Bu nedenle ana iş parçaları senkron olarak çalıştı ve bu da performans düşüşüne ve yanıt süresinde 3 kat artışa yol açtı.Hikaye
Hikaye
Takımın bir üyesi, Future içinde kullanılan türler için Send/Sync kısıtlamalarını unuttu. İş parçaları arasında future paylaşmaya çalıştığında uygulama, belirli bir yapı için Send'i uygulama gerektiren bir derleme hatası ile çöktü. Bu, durum depolama mimarisinin yeniden gözden geçirilmesini gerektirdi.