select!
- Rust kursu
- İleri seviye
- Ders 11/81
- 4 dk
tokio::select! ile birden çok future'ı aynı anda beklersin.
select!
tokio::select!, birden çok Future'ı aynı anda bekler ve ilk tamamlananın kolunu çalıştırır; diğerleri iptal edilir. Zaman aşımı ve iptal desenlerinin temelidir:
tokio::select! {
mesaj = rx.recv() => println!("geldi: {mesaj:?}"),
_ = tokio::time::sleep(Duration::from_secs(1)) => println!("zaman aşımı"),
_ = tokio::signal::ctrl_c() => println!("kapatılıyor"),
}Yalnızca zaman aşımı için daha kısa bir araç da vardır: tokio::time::timeout(süre, future).await.
std karşılığı: zaman aşımlı bekleme
Std kanallarında recv_timeout, mesaj ile süre arasında bir "yarış" kurar:
use std::sync::mpsc::{self, RecvTimeoutError};
use std::time::Duration;
match rx.recv_timeout(Duration::from_millis(500)) {
Ok(m) => println!("geldi: {m}"),
Err(RecvTimeoutError::Timeout) => println!("zaman aşımı"),
Err(RecvTimeoutError::Disconnected) => println!("gönderici kapandı"),
}Uygulama Zaman aşımı
Bir thread 10 ms uyuyup "hazır" göndersin; recv_timeout(500 ms) ile al. İkinci bir kanalda göndericiyi canlı tutup hiçbir şey gönderme ve recv_timeout(10 ms) ile bekle. İki sonucu {:?} ile boşlukla yazdır.
Başlangıç kodu
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
// buraya yaz
}Örnek çözüm
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
thread::sleep(Duration::from_millis(10));
tx.send("hazır").unwrap();
});
let a = rx.recv_timeout(Duration::from_millis(500));
let (_tx2, rx2) = mpsc::channel::<&str>();
let b = rx2.recv_timeout(Duration::from_millis(10));
println!("{:?} {:?}", a, b);
}Beklenen çıktı
Ok("hazır") Err(Timeout)
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 select!'te kaybeden Future'a ne olur?
- Panic
- Bırakılır (drop edilir); yaptığı yarım iş iptal olur Doğru cevap
- Arka planda tamamlanır
- Sonraki select!'te devam eder
Açıklama: Bu yüzden select! içindeki Future'ların iptale güvenli (cancel-safe) olması önemlidir.
2 Süreli bekle
match rx.____(Duration::from_millis(500)) {
Ok(m) => println!("{m}"),
Err(_) => println!("zaman aşımı"),
}
match rx.recv_timeout(Duration::from_millis(500)) {
Ok(m) => println!("{m}"),
Err(_) => println!("zaman aşımı"),
}
Açıklama: recv_timeout, süre dolarsa Timeout hatası döndürür.
3 Durum ve sonuç
| Kavram | Anlamı |
|---|---|
Mesaj süreden önce |
Ok(mesaj) |
Süre doldu |
Err(Timeout) |
Gönderici kapandı |
Err(Disconnected) |
select! kaybeden |
Drop edilir |