Ce face mpsc::channel
mpsc::channel() returnează o pereche (Sender, Receiver). Ce trimiți cu tx.send(valoare) ajunge, în ordinea trimiterii, la capătul rx. Valoarea este mutată prin canal, deci firul care a trimis-o nu o mai poate folosi.
„mpsc” înseamnă multiple producer, single consumer: Sender-ul se poate clona (tx.clone()) pentru mai multe fire care trimit, dar există un singur Receiver. Canalul nu are limită de mesaje; varianta cu limită este mpsc::sync_channel(n).
send returnează Err doar dacă Receiver-ul a dispărut. Când toate Sender-ele dispar, receptorul află că nu mai vin mesaje (bucla for m in rx se termină).
Ce returnează
channel: perechea (Sender<T>, Receiver<T>). send: Ok(()) sau Err(SendError(valoare)).
Exemple
Exemplul 1: Un fir trimite, main primește
Mesajele de la un singur Sender ajung în ordinea în care au fost trimise.
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
let producator = thread::spawn(move || {
for comanda in ["pizza", "supă", "salată"] {
tx.send(comanda.to_string()).unwrap();
}
});
for mesaj in rx {
println!("bucătăria a primit: {mesaj}");
}
producator.join().unwrap();
println!("nu mai vin comenzi");
}
Rezultat
bucătăria a primit: pizza
bucătăria a primit: supă
bucătăria a primit: salată
nu mai vin comenzi
Exemplul 2: Mai mulți producători
Fiecare fir are propriul Sender clonat. Mesajele de la fire diferite se amestecă în ordine variabilă, așa că le sortăm la final. drop(tx) închide originalul, altfel bucla nu s-ar termina.
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
for (id, oras) in ["Iași", "Cluj", "Brașov"].into_iter().enumerate() {
let tx = tx.clone();
thread::spawn(move || {
let temperatura = 10 + id as i32 * 3;
tx.send(format!("{oras}: {temperatura}°C")).unwrap();
});
}
drop(tx);
let mut rapoarte: Vec<String> = rx.iter().collect();
rapoarte.sort();
for r in rapoarte {
println!("{r}");
}
}
Rezultat
Brașov: 16°C
Cluj: 13°C
Iași: 10°C
Greșeli frecvente
- Uiți
drop(tx)pentruSender-ul original după ce ai dat clone firelor:for m in rxașteaptă la nesfârșit, pentru că unSenderîncă există. - Folosești valoarea după
send: a fost mutată prin canal. Trimite o copie sau unclone()dacă ai nevoie de ea în continuare.
Comenzi înrudite
Receiver: Capătul de primire al unui canal mpsc: recv() așteaptă următorul mesaj, try_recv() verifică fără să aștepte.thread::spawn: Pornește un fir de execuție nou care rulează funcția dată; join() așteaptă terminarea lui și îi dă rezultatul.Mutex: Protejează o valoare folosită din mai multe fire: lock() așteaptă până când firul curent este singurul cu acces.