Crossbeam-kanaler
Avanserte kanaler
Crossbeam-kanaler er en gratis leksjon i Lær Rust-programmering på CoddyKit. Dette er leksjon 4 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Lær Rust-programmering, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Lær Rust-programmering inneholder totalt 4 leksjoner.
Utover std mpsc
Standardkanalen mpsc har én mottaker: bare én receiver. Cratet crossbeam-channel tilbyr flere produsenter og flere mottakere (mpmc) med flere funksjoner og ofte bedre ytelse.
Høydepunkter:
- Receiver-er som kan klones, ikke bare sendere.
- En kraftig
select!-makro for å vente på mange kanaler. - Begrensede, ubegrensede og spesielle kanaler, for eksempel ticks.
Legge til avhengigheten
Crossbeam er et eksternt crate, så legg det til i Cargo.toml:
[dependencies]crossbeam-channel = "0.5"
Importer deretter funksjonene. Siden dette krever Cargo og et eksternt crate, viser kodeutdragene her API-et uten å kunne kjøres som frittstående kode.
// Cargo.toml
// [dependencies]
// crossbeam-channel = "0.5"
use crossbeam_channel::unbounded;
fn main() {
let (s, r) = unbounded();
s.send("hello").unwrap();
println!("{}", r.recv().unwrap());
}unbounded og bounded
Crossbeam tilbyr to hovedkonstruktører:
unbounded()vokser etter behov;sendblokkerer aldri.bounded(cap)har en buffer med fast størrelse;sendblokkerer når den er full, noe som gir mottrykk.
En bounded(0)-kanal er en rendezvous-kanal der send og recv overfører data direkte.
use crossbeam_channel::bounded;
use std::thread;
fn main() {
let (s, r) = bounded(2);
thread::spawn(move || {
for i in 1..=3 {
s.send(i).unwrap();
}
});
while let Ok(v) = r.recv() {
println!("got {}", v);
}
}Flere mottakere
Den viktigste fordelen er at De kan klone Receiver. Flere arbeidstråder kan hente fra den samme kanalen, og hver melding går til nøyaktig én av dem. Dette er grunnlaget for en trådpool med arbeidstyveri.
use crossbeam_channel::unbounded;
use std::thread;
fn main() {
let (s, r) = unbounded();
let mut workers = vec![];
for id in 0..3 {
let rx = r.clone();
workers.push(thread::spawn(move || {
while let Ok(job) = rx.recv() {
println!("worker {} got job {}", id, job);
}
}));
}
for job in 0..6 { s.send(job).unwrap(); }
drop(s);
for w in workers { w.join().unwrap(); }
}select!-makroen
select! lar én tråd vente på flere kanaloperasjoner og reagere på den som blir klar først. Den fungerer omtrent som en match over kanalhendelser og er ideell for å kombinere inndata fra flere kilder.
use crossbeam_channel::{unbounded, select};
use std::thread;
fn main() {
let (s1, r1) = unbounded();
let (s2, r2) = unbounded();
thread::spawn(move || { s1.send("from one").unwrap(); });
thread::spawn(move || { s2.send("from two").unwrap(); });
for _ in 0..2 {
select! {
recv(r1) -> msg => println!("r1: {}", msg.unwrap()),
recv(r2) -> msg => println!("r2: {}", msg.unwrap()),
}
}
}Tidsavbrudd med select!
select! støtter en default-gren og en tidtakergren med recv(after(duration)), slik at De kan slutte å vente etter et tidsavbrudd i stedet for å blokkere for alltid. Dette er avgjørende for responsive systemer.
use crossbeam_channel::{unbounded, select, after};
use std::time::Duration;
fn main() {
let (_s, r) = unbounded::<i32>();
select! {
recv(r) -> msg => println!("received {:?}", msg),
recv(after(Duration::from_millis(100))) -> _ => {
println!("timed out waiting for a message");
}
}
}try_send og try_recv
I likhet med standardbiblioteket tilbyr crossbeam varianter som ikke blokkerer. try_send mislykkes umiddelbart hvis en begrenset kanal er full; try_recv mislykkes umiddelbart hvis ingen melding er klar. Begge returnerer en beskrivende feil som De kan bruke i en match.
use crossbeam_channel::{bounded, TrySendError};
fn main() {
let (s, _r) = bounded(1);
s.send(1).unwrap();
match s.try_send(2) {
Ok(()) => println!("sent"),
Err(TrySendError::Full(v)) => println!("full, kept {}", v),
Err(TrySendError::Disconnected(v)) => println!("closed, kept {}", v),
}
}tick og periodisk arbeid
Funksjonen tick(duration) returnerer en mottaker som leverer en melding med et fast intervall. Kombiner den med select! for å kjøre periodiske oppgaver sammen med andre kanaler, for eksempel et heartbeat eller en pollingløkke.
use crossbeam_channel::{tick, select};
use std::time::Duration;
fn main() {
let ticker = tick(Duration::from_millis(50));
let mut count = 0;
while count < 3 {
select! {
recv(ticker) -> _ => {
count += 1;
println!("tick {}", count);
}
}
}
}En rørledning av trinn
Crossbeam utmerker seg når du bygger pipelines: trinn én produserer, trinn to transformerer, og trinn tre konsumerer. Hvert trinn kjører i sin egen tråd som er koblet sammen med kanaler, og klonede mottakere lar deg skalere ethvert trinn til flere arbeidere.
use crossbeam_channel::unbounded;
use std::thread;
fn main() {
let (in_s, in_r) = unbounded();
let (out_s, out_r) = unbounded();
thread::spawn(move || {
for n in in_r { out_s.send(n * n).unwrap(); }
});
for n in 1..=4 { in_s.send(n).unwrap(); }
drop(in_s);
for sq in out_r { println!("square: {}", sq); }
}Når Crossbeam er bedre enn std
Bruk crossbeam-channel når du trenger:
- Flere konsumenter som deler én kø (arbeiderpooler).
select!over mange kanaler med tidsavbrudd.- Periodiske tidtakere via
tick, integrert i utvalget.
For en enkel kanal med én produsent og én konsument fungerer standardbibliotekets mpsc fint, og den krever ingen avhengighet.
Kanaler lukkes når de forkastes
Akkurat som i std lukkes crossbeam-kanaler når alle senderne (på mottakersiden) eller alle mottakerne (på sendersiden) forkastes. Iterasjon over en mottaker avsluttes etter at den siste senderen forkastes. Bruk alltid drop, eller avgrens senderne til et scope, slik at arbeiderløkkene kan avsluttes på en ryddig måte.
use crossbeam_channel::unbounded;
use std::thread;
fn main() {
let (s, r) = unbounded();
let h = thread::spawn(move || {
let total: i32 = r.iter().sum();
println!("total: {}", total);
});
for i in 1..=5 { s.send(i).unwrap(); }
drop(s); // closes channel so the loop ends
h.join().unwrap();
}Kort kontroll
Test forståelsen Deres av crossbeam-kanaler.
Oppsummering
De har utforsket crossbeam-kanaler:
- De er mpmc: både sendere og mottakere kan klones.
unbounded()ogbounded(n)styrer bufring og mottrykk.select!venter på flere kanaler, med tidsavbrudd viaafterog periodisktick.try_send/try_recver ikke-blokkerende.- Bruk crossbeam til arbeiderpooler og komplekse pipelines, og std mpsc til enkle kanaler.
Lær deg Rust med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 39
- Leksjoner
- 144
Ofte stilte spørsmål
Er leksjonen «Crossbeam-kanaler» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Lær Rust-programmering, inkludert «Crossbeam-kanaler», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Lær Rust-programmering inneholder totalt 4 leksjoner.
Hva lærer jeg i «Crossbeam-kanaler»?
Avanserte kanaler Du øver på Lær Rust-programmering med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Lær Rust-programmering?
Ingen tidligere erfaring er nødvendig. Lær Rust-programmering på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «Crossbeam-kanaler»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Lær Rust-programmering-leksjonen?
Ja. Alle Lær Rust-programmering-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- mpsc-kanaler
- Dele tilstand med Arc/Mutex
- Avgrensede tråder
- Crossbeam-kanaler