Rust samtidighet

Rust samtidighet
Samtidig refererer til en funksjon som lar frittstående deler av et program kjøre parallelt med andre deler av koden. Samtidig lar forskjellige deler av et program kjøre samtidig, forbedre ytelsen.

La oss rusle gjennom skogen til samtidig programmering i rustprogrammeringsspråket. Husk at dette er artikkelen ikke er designet for å være en komplett guide til samtidig programmering. Det fungerer bare som et grunnlag for å utvide og lage mer komplekse applikasjoner.

Prosesser og tråder

Når vi skriver et normalt program og utfører det på et målsystem, utfører vertsoperativsystemet koden i en prosess. En prosess refererer til en enhet av en spesifisert kjørbar.

I moderne systemer og applikasjoner har du imidlertid deler av samme kode som kjøres samtidig ved hjelp av tråder.

I de fleste tilfeller vil du ofte høre begrepet flertråding som brukes der samtidighet oppstår. Dette er fordi vi i hovedsak gyper flere tråder og lar dem løpe parallelt med hverandre.

La oss ta et grunnleggende program for å illustrere hvordan et normalt program fungerer og hvordan vi bruker samtidighet for å forbedre det.

Vurder et program med to løkker som vist:

bruk std :: tråd;
Bruk std :: tid :: varighet;
fn main ()
for i i 0… = 5
Println!("", Jeg);
// sove i 1000 ms
Tråd :: Sov (varighet :: fra_millis (1000));

for i i 0… = 5
Println!("", Jeg);
Tråd :: Sov (varighet :: fra_millis (1000));

I eksempelkoden ovenfor har vi to løkker som itererer fra 0 til 5. Imidlertid sover vi i hver iterasjon for 1000 millisekunder.

Tråden :: Sleep Method lar oss legge en spesifikk tråd for å sove for den spesifiserte varigheten.

Hvis du kjører koden over, merker du at den første sløyfen venter på at den andre sløyfen skal fullføres før den kan begynne å løpe.

Dette er fordi begge løkkene er på en enkelt tråd.

Hvis vi vil at begge løkker skal kjøres samtidig, må vi legge dem i forskjellige tråder.

Rust lage tråd

Vi kan lage nye tråder ved hjelp av trådmodulen. Det er en del av standardbiblioteket og gir oss en serie verktøy og funksjoner for å jobbe med tråder.

Vi kan importere den ved hjelp av uttalelsen:

Bruk std :: tråd;

Vi trenger også varighetsmodulen fra tidstråden. Vi kan importere det som:

Bruk std :: Tid :: Varighet

For å lage en ny tråd i rust, bruk tråden :: gyte -metoden. Denne metoden tar en nedleggelse som argument.

Stengingen definerer i dette tilfellet koden for å kjøre inne i tråden.

Syntaksen er som vist nedenfor:

Tråd :: Spawn (|| Closure)

La oss avgrense den forrige koden og sette hver konstruksjon i en egen tråd. Eksempelkode er som vist:

bruk std :: tråd;
Bruk std :: tid :: varighet;
fn main ()
// Lag ny tråd
std :: tråd :: gyte (flytt ||
for i i 0… = 5
Println!("", Jeg);
Tråd :: Sov (varighet :: fra_millis (1000));

);
for i i 0… = 5
Println!("", Jeg);
Tråd :: Sov (varighet :: fra_millis (1000));

I eksempelprogrammet ovenfor lager vi en ny tråd ved hjelp av tråden :: gytefunksjon og passerer den første sløyfen som lukking.

I hovedtråden kjører vi den andre sløyfen. Dette lar begge løkker kjøres samtidig. Koden over skal returnere utdataene som:

0
0
1
1
2
2
3
3
4
4
5
5

Hva skjer hvis hovedtråden kommer ut før den "indre" tråden fullfører? Et eksempel er som vist nedenfor:

bruk std :: tråd;
Bruk std :: tid :: varighet;
fn main ()
// indre tråd
std :: tråd :: gyte (flytt ||
for i i 0… = 5
Println!("", Jeg);
Tråd :: Sov (varighet :: fra_millis (1000));

);
// Main
for i i 0… = 5
Println!("", Jeg);
Tråd :: Sov (varighet :: fra_millis (2));

I dette eksemplet tar hovedtråden mindre tid å sove og vil derfor fullføre raskere før den indre tråden fullføres.

I et slikt tilfelle vil den indre tråden bare kjøre mens hovedtråden kjører. Koden over vil returnere ufullstendige utgang som:

0
0
1
2
3
4
5

Dette er fordi den "indre" tråden avsluttes før ferdigstillelse.

Rust sammenføyningshåndtak

Vi har sett hvordan en tråd oppfører seg hvis hovedtråden kommer ut før den fullføres. Vi kan bli med de to håndtakene for å løse en slik sak og la den andre tråden vente på en annen.

Sammenføyning av håndtak lar hovedtråden vente på de andre trådene før avslutning.

For å slå sammen håndtak, bruker vi sammenføyningsmetoden som vist i syntaksen nedenfor:

La Handle_name = Tråd :: Spawn (Closure);
Håndtak.bli med().Unwrap ();

La oss omdefinere vårt sløyfeeksempel, der hovedtråden kommer ut tidlig.

bruk std :: tråd;
Bruk std :: tid :: varighet;
fn main ()
La håndtak = std :: tråd :: gyte (flytt ||
for i i 0… = 5
Println!("", Jeg);
Tråd :: Sov (varighet :: fra_millis (1000));

);
for i i 0… = 5
Println!("", Jeg);
Tråd :: Sov (varighet :: fra_millis (2));

// Bli med på håndtaket
håndtak.bli med().Unwrap ();

I eksempelkoden ovenfor lager vi en håndtaksvariabel som holder tråden. Vi blir deretter med i tråden ved hjelp av Join () -metoden.

Pakkemetoden lar oss håndtere feil.

Siden hovedtråden sover i kortere tid, bør den fullføres før "indre" tråden. Imidlertid bør den vente på at den andre tråden skal gå ut på grunn av sammenføyningsmetoden.

Utgangen er som vist:

0
0
1
2
3
4
5
1
2
3
4
5

Merk at hovedtråden gir ut alle verdiene i kort varighet og venter på at den andre tråden skal fullføres.

Rusttråd Move Closure

Du har kanskje lagt merke til flyttingsnøkkelordet inne i trådlukkingen i vårt forrige eksempel. Flyttingslukking brukes med tråden :: Spawn -metoden for å tillate deling av data mellom trådene.

Ved hjelp av flyttesnøkkelordet kan vi tillate en tråd å overføre eierskap til verdier til en annen tråd.

Ta et eksempelprogram nedenfor:

bruk std :: tråd;
Bruk std :: tid :: varighet;
fn main ()
La arr = [1,2,3,4,5];
La håndtaket = std :: tråd :: gyte (||
for jeg i arr.iter ()
Println!("", Jeg);
Tråd :: Sov (varighet :: fra_millis (100));

);
håndtak.bli med().Unwrap ();

I koden over erklærer vi en matrise som heter ARR i hovedtråden. Vi gyter en ny tråd uten at stengingen.

Merk: Siden vi prøver å få tilgang til Array ARR og gjøre det til en del av lukkemiljøet, vil samlingen mislykkes, da den ikke er tilgjengelig i den tråden.

Vi kan bruke flyttingsnøkkelordet for å tvinge nedleggelsen i tråden til å ta eierskap til matrisen.

Vi kan fikse koden ovenfor ved å legge til bevegelsen som vist:

bruk std :: tråd;
Bruk std :: tid :: varighet;
fn main ()
La arr = [1,2,3,4,5];
La håndtak = std :: tråd :: gyte (flytt ||
for jeg i arr.iter ()
Println!("", Jeg);
Tråd :: Sov (varighet :: fra_millis (100));

);
håndtak.bli med().Unwrap ();

Dette gjør at tråden kan ta eierskap til matrisen og iterere den. Dette skulle komme tilbake:

1
2
3
4
5

Konklusjon

Det var grunnleggende om samtidig programmering i rustprogrammeringsspråket. Selv om denne artikkelen fungerer som et konkret grunnlag for rustkall, dekker den ikke avanserte konsepter. Du kan sjekke dokumentasjonen for detaljer.