CodeBlanks Logo Icon CodeBlanks

Birden çok üretici

tx.clone() ile birden çok üreticili kanal oluşturursun.

Birden çok üretici

mpsc'nin "multiple producer" kısmı: göndericiyi clone ile çoğaltıp her üreticiye bir kopya verebilirsin. Tüm mesajlar tek alıcıda toplanır (fan-in):

let (tx, rx) = mpsc::channel();
for id in 0..3 {
    let tx = tx.clone();
    thread::spawn(move || {
        for j in 0..2 {
            tx.send(format!("üretici {id}: {j}")).unwrap();
        }
    });
}
drop(tx);   // ana kopya bırakılmazsa rx hiç kapanmaz

Farklı üreticilerin mesajları iç içe geçebilir; yalnızca aynı üreticinin mesajları kendi aralarında sıralıdır.

Belirleyici çıktı

Mesajların varış sırası çalıştırmadan çalıştırmaya değişir. Test edilebilir çıktı için mesajlar toplanıp sıralanır ya da yalnızca sıradan bağımsız özetler yazdırılır:

let mut hepsi: Vec<String> = rx.iter().collect();
hepsi.sort();
println!("{} {}", hepsi.len(), hepsi[0]);

Uygulama Üç üretici

Üç üretici thread başlat; her biri üretici ID: J biçiminde iki mesaj göndersin (J = 0, 1). Ana göndericiyi bırak, tüm mesajları topla, sırala; mesaj sayısını ve ilk mesajı boşlukla yazdır.

Başlangıç kodu

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

fn main() {
    // buraya yaz
}

Örnek çözüm

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

fn main() {
    let (tx, rx) = mpsc::channel();
    for id in 0..3 {
        let tx = tx.clone();
        thread::spawn(move || {
            for j in 0..2 {
                tx.send(format!("üretici {id}: {j}")).unwrap();
            }
        });
    }
    drop(tx);
    let mut hepsi: Vec<String> = rx.iter().collect();
    hepsi.sort();
    println!("{} {}", hepsi.len(), hepsi[0]);
}

Beklenen çıktı

6 üretici 0: 0

Soru ve cevaplar

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

1 Alıcı kopyalanabilir mi (<code>rx.clone()</code>)?

  • Yalnızca tokio'da
  • Hayır; mpsc tek tüketicilidir Doğru cevap
  • Evet
  • Yalnızca Arc ile

Açıklama: Çok tüketici gerekiyorsa alıcı Arc<Mutex<Receiver>> içine konur ya da crossbeam/tokio broadcast kanalları kullanılır.

2 Göndericiyi çoğalt

Soru
for id in 0..3 {
    let tx = tx.____();
    thread::spawn(move || tx.send(id).unwrap());
}
Cevap
for id in 0..3 {
    let tx = tx.clone();
    thread::spawn(move || tx.send(id).unwrap());
}

Açıklama: Sender::clone aynı kanala yeni bir gönderici verir.

3 Kavram ve anlamı

Kavram Anlamı
tx.clone() Yeni üretici
fan-in Çoktan teke toplama
drop(tx) Ana kopyayı kapat
rx.clone() Mümkün değil

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