Crossbeam-kanavat
Edistyneet kanavat.
Crossbeam-kanavat on ilmainen Rust-ohjelmoinnin perusteet-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Rust-ohjelmoinnin perusteet-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Rust-ohjelmoinnin perusteet-kurssilla on yhteensä 4 oppituntia.
std:n mpsc:n tuolle puolen
Standardin mpsc-kanavan kuluttajia on vain yksi: vastaanottimia on vain yksi. crossbeam-channel-crate tarjoaa usean tuottajan ja usean kuluttajan (mpmc) kanavat, joissa on enemmän ominaisuuksia ja usein parempi suorituskyky.
Tärkeimmät ominaisuudet:
- Kloonattavat
Receiver-vastaanottimet, eivät vain lähettimet. - Tehokas
select!-makro, jolla voidaan odottaa useita kanavia. - Rajatut, rajoittamattomat ja erityiskanavat, kuten tikityskanavat.
Riippuvuuden lisääminen
Crossbeam on ulkoinen crate, joten lisää se tiedostoon Cargo.toml:
[dependencies]crossbeam-channel = "0.5"
Tuo sen jälkeen sen funktiot käyttöön. Koska tämä vaatii Cargon ja ulkoisen craten, tässä olevat koodikatkelmat havainnollistavat ohjelmointirajapintaa eivätkä toimi itsenäisesti.
// 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 ja bounded
Crossbeam tarjoaa kaksi pääasiallista konstruktoria:
unbounded()kasvaa tarpeen mukaan;sendei koskaan estä suoritusta.bounded(cap)käyttää kiinteän kokoista puskuria;sendestää suorituksen puskurin ollessa täynnä ja tuottaa takapainetta.
bounded(0)-kanava on kättelykanava, jossa send ja recv luovuttavat arvon suoraan toisilleen.
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);
}
}Useita kuluttajia
Keskeinen etu on, että Receiverin voi kloonata. Useat työskentelijäsäikeet voivat noutaa viestejä samasta kanavasta, ja kukin viesti päätyy täsmälleen yhdelle niistä. Tämä muodostaa työvarastavan säiepoolin perustan.
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!-makro
select! sallii yhden säikeen odottaa useita kanavaoperaatioita ja toimia sen mukaan, mikä niistä valmistuu ensin. Se muistuttaa kanavatapahtumien match-rakennetta ja sopii erinomaisesti useiden lähteiden syötteiden yhdistämiseen.
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()),
}
}
}Aikakatkaisut select!-makrolla
select! tukee default-haaraa ja recv(after(duration))-ajastinhaaraa, joten odottamisen voi lopettaa aikakatkaisun jälkeen sen sijaan, että suoritus estyisi ikuisesti. Tämä on olennaista reagoivissa järjestelmissä.
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 ja try_recv
Standardikirjaston tavoin crossbeam tarjoaa suorituskykyä estämättömät versiot. try_send epäonnistuu välittömästi, jos rajattu kanava on täynnä; try_recv epäonnistuu välittömästi, jos viestiä ei ole valmiina. Molemmat palauttavat kuvaavan virheen, jonka voi käsitellä match-rakenteella.
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 ja jaksottainen työ
tick(duration)-funktio palauttaa vastaanottimen, joka toimittaa viestin kiintein aikavälein. Yhdistä se select!-makroon suorittaaksesi jaksottaisia tehtäviä muiden kanavien rinnalla, esimerkiksi sydämenlyönti- tai kyselysilmukan.
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);
}
}
}
}Vaiheista koostuva putki
Crossbeam soveltuu erinomaisesti putkistojen rakentamiseen: ensimmäinen vaihe tuottaa dataa, toinen muuntaa sitä ja kolmas kuluttaa sitä. Kukin vaihe suoritetaan omassa säikeessään, ja vaiheet yhdistetään kanavilla. Kloonattujen vastaanottimien avulla minkä tahansa vaiheen voi skaalata useille työntekijöille.
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); }
}Milloin Crossbeam päihittää std:n
Valitkaa crossbeam-channel, kun tarvitsette:
- Useita kuluttajia jakamaan yhden jonon (työntekijäpoolit).
select!-valintaa useiden kanavien välillä aikakatkaisuineen.- Jaksottaisia ajastimia
tick-toiminnolla, joka on integroitu valintaan.
Yksinkertaiseen yhden tuottajan ja yhden kuluttajan putkeen standardin mpsc-kanava riittää, eikä se tarvitse riippuvuuksia.
Kanavat suljetaan pudottamalla
Kuten std-kanavat, myös crossbeam-kanavat sulkeutuvat, kun kaikki lähettäjät (vastaanottajan puolella) tai kaikki vastaanottajat (lähettäjän puolella) pudotetaan. Vastaanottimen iteraatio päättyy, kun viimeinen lähettäjä pudotetaan. Kutsukaa aina drop-funktiota lähettäjille tai rajatkaa niiden näkyvyys lohkoon, jotta työntekijäsäikeiden silmukat voivat päättyä siististi.
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();
}Pikatarkistus
Testatkaa, miten hyvin ymmärrätte crossbeam-kanavia.
Kertaus
Tutustuitte crossbeam-kanaviin:
- Ne ovat mpmc-kanavia: sekä lähettäjiä että vastaanottajia voi kloonata.
unbounded()jabounded(n)määrittävät puskuroinnin ja vastapaineen.select!odottaa useita kanavia; aikakatkaisut toteutetaanafter-toiminnolla ja jaksottainen toimintatick-toiminnolla.try_send/try_recvovat estämättömiä.- Käyttäkää crossbeamia työntekijäpooleihin ja monimutkaisiin putkistoihin; käyttäkää std mpsc:tä yksinkertaisiin putkiin.
Opi Rust tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 39
- Oppitunnit
- 144
Usein kysytyt kysymykset
Onko oppitunti ”Crossbeam-kanavat” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Rust-ohjelmoinnin perusteet-oppimispolun 3 oppituntia, myös oppitunnin “Crossbeam-kanavat”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Rust-ohjelmoinnin perusteet-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Crossbeam-kanavat”?
Edistyneet kanavat. Harjoittelet Rust-ohjelmoinnin perusteet-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Rust-ohjelmoinnin perusteet-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Rust-ohjelmoinnin perusteet-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”Crossbeam-kanavat”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Rust-ohjelmoinnin perusteet-oppitunnilla?
Kyllä. Jokainen Rust-ohjelmoinnin perusteet-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- mpsc-kanavat
- Tilan jakaminen Arc/Mutexilla
- Rajatut säikeet
- Crossbeam-kanavat