CodeBlanks Logo Icon CodeBlanks

send ve recv

send ve recv ile mesajlaşmayı öğrenirsin.

send ve recv

Her iki işlem de karşı tarafın kapanmasını bildirebilir:

  • tx.send(v) alıcı bırakılmışsa Err(SendError(v)) döndürür ve değeri geri verir.
  • rx.recv() mesaj gelene kadar bekler; tüm göndericiler bırakılmışsa ve kanal boşsa Err(RecvError) döndürür.
let (tx, rx) = mpsc::channel::<i32>();
drop(rx);
println!("{}", tx.send(1).is_err());   // true: dinleyen yok

Bu hatalar, bir thread'in diğerinin bittiğini anlamasının temiz yoludur.

Kapanmayı ele almak

Bir işçi, ana thread kapandığında sessizce durmalıdır:

thread::spawn(move || loop {
    let veri = hesapla();
    if tx.send(veri).is_err() {
        break;   // alıcı gitti, çalışmayı bırak
    }
});

recv tarafında da while let Ok(m) = rx.recv() deseni aynı işi görür.

Uygulama Kapanma hataları

Bir kanalın alıcısını bırakıp send(1).is_err() sonucunu yazdır. Başka bir kanalın göndericisini bırakıp recv() sonucunu {:?} ile yazdır.

Başlangıç kodu

main.rs
use std::sync::mpsc;

fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel::<i32>();
    drop(rx);
    println!("{}", tx.send(1).is_err());
    let (tx2, rx2) = mpsc::channel::<i32>();
    drop(tx2);
    println!("{:?}", rx2.recv());
}

Beklenen çıktı

true
Err(RecvError)

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Neden <code>send</code> hata durumunda değeri geri verir?

  • Gelenek
  • Vermez
  • Değer kaybolmasın; başka bir yere gönderilebilir ya da kaydedilebilir Doğru cevap
  • Bellek sızıntısını önlemek için

Açıklama: SendError(v).0 ile değere geri ulaşılır.

2 Alıcı kapandı mı?

Soru
if tx.send(veri).____() {
    break;
}
Cevap
if tx.send(veri).is_err() {
    break;
}

Açıklama: send alıcı yoksa Err döndürür.

3 Durum ve sonuç

Kavram Anlamı
rx bırakıldı + send Err(SendError(v))
tx bırakıldı + recv (boş) Err(RecvError)
Mesaj var + recv Ok(mesaj)
while let Ok(m) = rx.recv() Kapanınca biter

İleri seviye bölümündeki tüm dersler