Rust
select!
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.
Örnek çözümü göster
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);
}
Kendini test et
-
select!'te kaybeden Future'a ne olur?
- Panic
- Bırakılır (drop edilir); yaptığı yarım iş iptal olur
- Arka planda tamamlanır
- Sonraki select!'te devam eder
Cevabı göster
Bırakılır (drop edilir); yaptığı yarım iş iptal olur — Bu yüzden select! içindeki Future'ların iptale güvenli (cancel-safe) olması önemlidir.
-
Süreli bekle
match rx.____(Duration::from_millis(500)) {
Ok(m) => println!("{m}"),
Err(_) => println!("zaman aşımı"),
}
Cevabı göster
match rx.recv_timeout(Duration::from_millis(500)) {
Ok(m) => println!("{m}"),
Err(_) => println!("zaman aşımı"),
}
-
Durum ve sonuç
- Mesaj süreden önce
- Ok(mesaj)
- Süre doldu
- Err(Timeout)
- Gönderici kapandı
- Err(Disconnected)
- select! kaybeden
- Drop edilir
Sıradaki ders: Özet - Tokio