Huoleton rinnakkaisuus säikeillä
Perehdytte Rustin rinnakkaisohjelmoinnin perusmekanismeihin, kuten säikeisiin ja viestien välitykseen, jotka varmistavat datakilpailujen puuttumisen.
Huoleton rinnakkaisuus säikeillä on ilmainen Rust-ohjelmoinnin perusteet-oppitunti CoddyKitissä. Tämä on oppitunti 3/3. 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ä 3 oppituntia.
Samanaikaisuuden perusteet
Tervetuloa oppitunnille Fearless Concurrency with Threads! Tässä oppitunnissa opitte, miten Rust-ohjelma saadaan tekemään useita asioita samanaikaisesti.
Samanaikaisuus tarkoittaa useiden laskentatehtävien suorittamista näennäisesti samaan aikaan. Se on tärkeää reagoiville sovelluksille ja nykyaikaisten moniydinprosessorien hyödyntämiselle.
- Säikeet ovat ohjelman sisällä suoritettavia kevyitä yksiköitä.
- Kukin säie voi suorittaa eri osaa koodistanne.
- Rustin omistajuusjärjestelmä auttaa estämään yleisiä samanaikaisuuden virheitä.
Ensimmäisen säikeen luominen
Rust tarjoaa uusien säikeiden luomiseen funktion std::thread::spawn. Sille välitetään sulkeuma (anonyymi funktio), joka sisältää uuden säikeen suoritettavan koodin.
Kokeilkaa suorittaa tämä esimerkki nähdäksenne säikeet toiminnassa:
use std::thread;
use std::time::Duration;
fn main() {
println!("Hello from the main thread!");
thread::spawn(|| {
for i in 1..=5 {
println!("Hi number {} from the spawned thread!", i);
thread::sleep(Duration::from_millis(1));
}
});
for i in 1..=3 {
println!("Hi number {} from the main thread!", i);
thread::sleep(Duration::from_millis(1));
}
}Säikeiden odottaminen `join`-metodilla
Edellisessä esimerkissä luotu säie ei ehkä ehdi valmistua ennen pääsäikeen lopettamista. Tämä johtuu siitä, että pääsäie ei oletusarvoisesti odota luotuja säikeitä.
Varmistaaksemme, että luotu säie saa työnsä valmiiksi, käytämme sen JoinHandle-arvon metodia join(). Tämä estää nykyistä säiettä jatkamasta, kunnes yhdistetty säie on valmis.
use std::thread;
use std::time::Duration;
fn main() {
let handle = thread::spawn(|| {
for i in 1..=5 {
println!("Thread: {}", i);
thread::sleep(Duration::from_millis(1));
}
});
for i in 1..=3 {
println!("Main: {}", i);
thread::sleep(Duration::from_millis(1));
}
handle.join().unwrap(); // Wait for the spawned thread to finish
println!("Spawned thread has finished!");
}Datan siirtäminen säikeisiin
Kun käytätte ympäristön muuttujia spawn-sulkeuman sisällä, Rustin omistajuussäännöt tulevat mukaan. Oletusarvoisesti sulkeumat yrittävät lainata muuttujia.
Jos luotu säie jatkaa suorittamista sen näkyvyysalueen jälkeen, jossa muuttuja määriteltiin, seurauksena voi olla riippuva viite. Korjataksenne tämän käyttäkää move-avainsanaa ennen sulkeuman parametreja.
movepakottaa sulkeuman ottamaan omistajuuden kaapatuista muuttujistaan.- Näin data säilyy kelvollisena uuden säikeen koko elinkaaren ajan.
use std::thread;
fn main() {
let data = String::from("Hello from outer scope");
let handle = thread::spawn(move || { // Use 'move' to take ownership of 'data'
println!("Data in thread: {}", data);
});
handle.join().unwrap();
// println!("Data after thread: {}", data); // This would cause a compile error!
println!("Main thread finished.");
}Kommunikointi viestinvälityksellä
Datan suora jakaminen säikeiden välillä (jaettu tila) on Rustissa mahdollista, mutta se edellyttää huolellista synkronointia (esimerkiksi Mutex- ja Arc-tyypeillä, joita käsitellään muilla oppitunneilla).
Turvallisempi ja usein yksinkertaisempi tapa toteuttaa samanaikaisuutta on viestinvälitys. Säikeet kommunikoivat lähettämällä viestejä toisilleen, jolloin suoraa pääsyä jaettuun muistiin ei tarvita.
- Yksi säie lähettää dataa.
- Toinen säie vastaanottaa dataa.
- Rustin standardikirjasto tarjoaa tätä varten tyypin
std::sync::mpsc.
`mpsc`-kanavan määrittäminen
std::sync::mpsc on lyhenne sanoista Multiple Producer, Single Consumer. Tämä tarkoittaa, että monet säikeet voivat lähettää viestejä, mutta vain yksi säie voi vastaanottaa niitä.
Kanava luodaan kutsumalla funktiota mpsc::channel(). Se palauttaa tuplen, joka sisältää:
- Sender-arvon (
tx): viestien lähettämiseen. - Receiver-arvon (
rx): viestien vastaanottamiseen.
Seuraavaksi näemme, miten kanava luodaan ja miten lähetetään yksinkertainen viesti.
use std::sync::mpsc;
use std::thread;
fn main() {
// Create a new channel
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
tx.send(val).unwrap(); // Send the message
// println!("val is {}", val); // Error: val moved to tx.send()
});
// Receive the message in the main thread
let received = rx.recv().unwrap();
println!("Got: {}", received);
}Useiden viestien lähettäminen
Saman kanavan kautta voi lähettää useita viestejä. Receiver tarjoaa tähän seuraavat metodit:
rx.recv(): Estää nykyistä säiettä, kunnes viesti vastaanotetaan. PalauttaaResult-arvon.rx.try_recv(): Ei estä suoritusta. PalauttaaResult-arvon heti: joko viestin tai virheen, jos viestiä ei ole saatavilla.Receiver-arvon voi myös käydä suoraan läpi iteraattorina viestien saamiseksi, kunnes lähettäjä sulkee kanavan.
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let msgs = vec!["hi", "from", "the", "thread"];
for msg in msgs {
tx.send(String::from(msg)).unwrap();
thread::sleep(Duration::from_millis(10));
}
});
// Iterate over the receiver to get all messages
for received in rx {
println!("Got: {}", received);
}
println!("All messages received!");
}Useita lähettäjiä, yksi vastaanottaja
mpsc-lyhenteen "MP" tarkoittaa Multiple Producers. Sender-arvosta voi tehdä kloonin, jolloin useat säikeet voivat lähettää viestejä samalle Receiver-arvolle.
Jokainen kloonattu Sender jakaa pääsyn samaan kanavaan, mikä mahdollistaa viestien samanaikaisen lähettämisen eri säikeistä.
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
fn main() {
let (tx, rx) = mpsc::channel();
let tx1 = tx.clone(); // Clone the sender for another thread
thread::spawn(move || {
tx1.send(String::from("hello from tx1")).unwrap();
});
thread::spawn(move || {
tx.send(String::from("hello from tx2")).unwrap();
});
// Collect all messages
let mut received_messages: Vec<String> = vec![];
for received in rx {
received_messages.push(received);
if received_messages.len() == 2 { break; } // Assuming 2 messages for this example
}
println!("Received: {:?}", received_messages);
}Peloton samanaikaisuus Rustilla
Rustin omistajuus- ja tyyppijärjestelmät ovat ratkaisevan tärkeitä pelottoman samanaikaisuuden saavuttamisessa. Valvomalla sääntöjä käännösaikana Rust estää yleisiä samanaikaisuuden virheitä, kuten datakilpailuja.
- Omistajuus estää useat muunneltavat viitteet samaan dataan.
move-avainsana varmistaa, että data siirretään turvallisesti uuteen säikeeseen.- Viestinvälitys (
mpsc) poistaa jaetun muistin tarpeen kokonaan, joten kommunikointi on turvallista rakenteensa ansiosta.
Näiden mekanismien avulla voitte kirjoittaa samanaikaista koodia luottavaisin mielin, sillä kääntäjä havaitsee monia mahdollisia ongelmia.
Samanaikaisuuden käsitteiden tarkistus
Mitkä seuraavista Rustin samanaikaisuusprimitiivejä koskevista väitteistä ovat TOSIA?
Kertaus: säikeet ja viestinvälitys
Hienoa työtä! Olette oppineet Rustin pelottoman samanaikaisuuden perusteet:
- Luomme uusia säikeitä käyttämällä funktiota
std::thread::spawn. - Käytämme metodia
JoinHandle::join()odottamaan säikeen valmistumista. move-avainsana siirtää datan omistajuuden turvallisesti säikeeseen.std::sync::mpsctarjoaa tehokkaan viestinvälitysjärjestelmän säikeiden väliseen kommunikointiin.- Rustin omistajuussäännöt estävät datakilpailut käännösaikana, mikä tekee samanaikaisesta ohjelmoinnista turvallisempaa.
Tämä oppitunti tarjoaa vankan perustan reagoivien ja tehokkaiden sovellusten rakentamiseen. Jatkakaa harjoittelua!
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 ”Huoleton rinnakkaisuus säikeillä” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Rust-ohjelmoinnin perusteet-oppimispolun 3 oppituntia, myös oppitunnin “Huoleton rinnakkaisuus säikeillä”. 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ä 3 oppituntia.
Mitä opin oppitunnilla ”Huoleton rinnakkaisuus säikeillä”?
Perehdytte Rustin rinnakkaisohjelmoinnin perusmekanismeihin, kuten säikeisiin ja viestien välitykseen, jotka varmistavat datakilpailujen puuttumisen. 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 3/3.
Kuinka kauan ”Huoleton rinnakkaisuus säikeillä”-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
- Box-, Rc- ja Arc-älyosoittimet
- Sisäinen muokattavuus: RefCell ja Cell
- Huoleton rinnakkaisuus säikeillä