Tutoriali i Rust-it: Siguria e Memorjes dhe Konkurrenca

Përditësimi i fundit: 04/12/2025
Author: Isaac
  • Rust siguron sigurinë e memories gjatë kompilimit përmes pronësisë, huazimit dhe jetëgjatësisë, pa përdorur mbledhjen e mbeturinave.
  • Sistemi i tipeve dhe rregullat e aliasing-ut lejojnë paralelizmin pa gara të dhënash duke përdorur mutexes, kanale dhe pointerë inteligjentë.
  • Cargo, crates.io dhe një ekosistem aktiv thjeshtojnë menaxhimin, përpilimin, testimin dhe vendosjen e varësive.
  • Të kuptuarit e strukturave, enumeve, Opsionit dhe Resultit është çelësi për trajtimin e gabimeve dhe modelimin e të dhënave të sigurta në aplikacione të njëkohshme.

Gjuha e programimit C kundrejt Rust: avantazhet dhe disavantazhet

Rust është bërë një nga ato gjuhë që Çdo zhvillues sistemesh përfundon duke e dëgjuar atë vazhdimisht.Është po aq i shpejtë sa C dhe C++, por me një fokus pothuajse obsesiv në sigurinë e memories dhe në njëkohshmërinë e ekzekutuar mirë. Ky nuk është thjesht marketing bosh: dizajni i tij sillet rreth përpiluesit që zbulon gabimet në kohën e përpilimit - gabime që në gjuhë të tjera i shihni vetëm kur sistemi është tashmë në prodhim... ose kur rrëzohet.

Nëse jeni të interesuar të kuptoni Si Rust arrin memorie të sigurt pa mbledhjen e mbeturinave dhe paralelizmin pa frikën e ekzekutimit të të dhënaveKy tutorial është për ju. Do të mbulojmë gjithçka, nga bazat e gjuhës dhe ekosistemit të saj deri te konceptet kryesore si pronësia, huazimi, llojet e përbëra, mjetet si Cargo, dhe madje do të hedhim një vështrim mbi llojet atomike dhe bllokimin nga një perspektivë më e arritshme për ata që janë të rinj në konkurencë, të gjitha me fokus në siguri dhe performancë.

Tutoriali i Rust: Performanca, Siguria e Memorjes dhe Konkurrenca

Rust është një gjuhë programimi programimi qëllim të përgjithshëm dhe shumëparadigmë, të projektuara për programim sistemesh të nivelit të ulët, si dhe për projekte të nivelit të lartë, qysh sisteme operativeNga motorët e lojërave dhe shfletuesit te shërbimet web me performancë të lartë, ai e ka origjinën në Mozilla me qëllim përmirësimin e sigurisë së softuerit, veçanërisht në komponentët e ndjeshëm si një motor shfletuesi.

Karakteristika e saj përcaktuese është se garanton sigurinë e memories në kohën e kompajlimit pa përdorur një mbledhës mbeturinash. Në vend të kësaj, Rust përdor një sistem pronësie dhe një kontrollues huash që gjurmon jetëgjatësinë e secilës vlerë dhe referencave të saj. Kjo shmang problemet klasike si treguesit e varur, tejmbushjet e memorjes ose rrjedhjet e memories pa kërkuar numërim automatik të referencave ose mbledhje mbeturinash.

Për më tepër, Rust është projektuar për ta bërë më të lehtë paralelizëm i sigurtLloji dhe modeli i pronësisë së tij parandalon garat e të dhënave midis fijeve, të paktën duke mbetur në kodin Rust të sigurt. Kjo do të thotë që shumë situata të rrezikshme zbulohen në kohën e kompajlimit, përpara se të ekzekutohet një rresht i vetëm.

Për të gjitha këto arsye, kompani të mëdha si Dropbox, Microsoft, Amazon ose Google Ata e kanë përvetësuar Rust në pjesë kritike të infrastrukturës së tyre. Dhe nuk është rastësi që ajo ka kryesuar sondazhet e Stack Overflow për vite me radhë si një nga gjuhët "më të dashura" nga zhvilluesit: ajo kombinon performancën në stilin C++ me një grup mjetesh moderne (Cargo, crates.io) dhe një komunitet shumë aktiv, të ashtuquajturit Rustaceans.

Konceptet themelore: gjuha e programimit, llojet dhe memoria

Para se të futemi në specifikat e sigurisë së memories dhe të njëkohshmërisë, ia vlen të sqarojmë disa koncepte të përgjithshme që shfaqen në të gjithë tekstin. el tiempo Kur punoni me Rust, veçanërisht nëse vini nga gjuhë të tjera ose sapo keni filluar të programoni.

Një gjuhë programimi, në fund të fundit, është një grup rregullash dhe strukturash që ju lejojnë të përshkruani algoritmet dhe i transformon ato në programe të ekzekutueshme. Rust kompilohet në kodin vendas të makinës duke përdorur kompiluesin e tij. rustcPrandaj, performanca që merrni është zakonisht në të njëjtin nivel me C dhe C++.

Menaxhimi i kujtesës është procesi me anë të të cilit një program rezervon dhe liron blloqe memorieje gjatë ekzekutimitGabimet në këtë fushë janë shpesh fatale: rrjedhjet e memories (moslirimi i memories së papërdorur), korruptimi i të dhënave nga shkrimi jashtë kufijve ose përdorimi i memories pasi ajo është liruar. Rust e adreson këtë me një sistem shumë të fortë tipash dhe rregulla formale për pronësinë, huazimin dhe jetëgjatësinë.

Rust gjithashtu përmban terma si lloje dhe tregues të zgjuarNjë lloj përshkruan se çfarë lloj të dhënash ruan një variabël (numra të plotë, numra me dendësi, vargje, struktura, etj.) dhe si mund të manipulohen ato. Tregues inteligjentë (për shembull, Box, Rc y Arc) janë struktura që enkapsulojnë adresat e memories dhe shtojnë logjikë shtesë për të menaxhuar burimet në mënyrë të sigurt, siç është numërimi i referencave të përbashkëta ose zhvendosja e vlerave në grumbull.

Në fushën e konkurrencës, koncepte të tilla si kushtet e garës, mutekset dhe kanalet Ato bëhen të domosdoshme: një kusht gare ndodh kur fije të shumta qasen dhe modifikojnë një burim të përbashkët njëkohësisht pa koordinim të duhur; një mutex (përjashtim i ndërsjellë) siguron që vetëm një fije të hyjë në seksionin kritik në të njëjtën kohë; dhe kanalet lejojnë që mesazhet të dërgohen midis fijeve pa ndarë drejtpërdrejt memorien.

Pse të mësosh Rust: Siguria e kujtesës dhe bashkëveprimi i patrembur

Rust ka fituar famën e tij sepse ofron tre shtylla shumë të vlefshme për programimin modernPerformanca, siguria dhe mjetet aktuale. Le të shohim pse këto pika janë kaq të rëndësishme.

Lidhur me performancën, Rust kompilohet direkt në skedarët binare native pa pasur nevojë për një makinë virtuale ose interpretues. Modeli i abstraksioneve me kosto zero synon të sigurojë që abstraksionet e nivelit të lartë të mos shtojnë mbingarkesë gjatë kohës së ekzekutimit. Prandaj, është ideal për zhvillimin e sistemeve. lojë, komponentët e shfletuesit ose mikroshërbimet me latencë të ulët.

Siguria e kujtesës bazohet në të sistemi i pronësisë dhe i huasëNuk ka një sistem për mbledhjen e mbeturinave, por kompiluesi e di saktësisht se kush e zotëron secilin burim, kur nuk nevojitet më dhe kur mund të lirohet. Kjo parandalon rrjedhjet, treguesit e varur dhe shumë nga gabimet që tradicionalisht e kanë bërë programimin në C dhe C++ kaq të rrezikshëm.

Në fushën e konkurrencës, Rust ndjek atë që zakonisht quhet "Bashkëpunim pa frikë"Vetë sistemi i tipit parandalon ekzistencën e rrënjëve të të dhënave në kodin e sigurt. Nëse doni të ndani të dhëna të ndryshueshme midis fijeve, do t'ju duhet të përdorni primitivë të përshtatshëm si p.sh. Mutex, RwLock o Arc, dhe kompiluesi do të sigurojë që rregullat e aliasing-ut dhe të ndryshueshmërisë të respektohen.

  Si ta riktheni ikonën e koshit të riciklimit në Windows 11 dhe të përfitoni sa më shumë nga cilësimet e tij

Përvoja e zhvillimit është përmirësuar me mjete moderne si p.sh. ngarkesëAi përmban një menaxhues paketash dhe infrastrukturë ndërtimi të integruar, si dhe një ekosistem të gjerë librarish (arkash) që mbulojnë gjithçka, nga rrjetëzimi asinkron (Tokio) deri te kornizat web (Actix, Rocket, Axum). E gjithë kjo mbështetet nga një komunitet i hapur, produktiv dhe mjaft i durueshëm, veçanërisht për fillestarët.

Instalimi dhe mjetet thelbësore: rustup, rustc dhe Cargo

Për të shkruar dhe ekzekutuar programet tuaja të para në Rust, mënyra e zakonshme për të filluar është duke instaluar zinxhirin zyrtar të mjeteve duke përdorur shushurimë (shih Hyrje e plotë në Rust), një instalues ​​dhe menaxher versionesh i thjeshtë që funksionon në të gjitha sistemet kryesore operative.

me shushurimë Mund të instaloni, përditësoni dhe kaloni midis versioneve të ndryshme të Rust (stabile, beta, çdo natë) pa shkaktuar probleme. Thjesht shkoni te faqja zyrtare e mjeteve të Rust dhe ndiqni hapat për sistemin tuaj. Pasi të instalohet, kompiluesi do të jetë i disponueshëm. rustc, menaxheri i projektit cargo dhe të tijat rustup në tuajin terminal.

përpiluesi rustc Është ajo që e transformon kodin burimor në skedarë binarë ose librari të ekzekutueshëm. Edhe pse mund ta thirrni direkt me komandat si rustc main.rsNë praktikë, pothuajse gjithmonë do të punoni përmes Cargo, i cili merret me thirrjet për rustc me opsionet e duhura.

Mjeti qendror i rrjedhës së punës është ngarkesëMe vetëm disa komanda, mund të krijoni projekte të reja, të menaxhoni varësi, të kompiloni, ekzekutoni, testoni dhe publikoni paketa në crates.io. Disa komanda bazë që përdoren zakonisht janë: cargo new, cargo build, cargo run, cargo test y cargo check, i cili kontrollon kodin pa prodhuar skedarin përfundimtar ekzekutues, ideal për zbulimin e shpejtë të gabimeve.

Nëse doni të bëni ndryshime pa instaluar asgjë, Shesh lojërash Rust (ekzekutuesi zyrtar online) dhe platforma si Replit ju lejojnë të shkruani dhe ekzekutoni pjesë të vogla kodi nga shfletuesi, perfekte për të eksperimentuar me shembuj të memories dhe të paralelizmit pa pasur nevojë të konfiguroni të gjithë mjedisin.

Programi juaj i parë: Përshëndetje, Rust dhe rrjedha bazë

Mënyra klasike për të filluar një bisedë në çdo gjuhë është me të famshmen "Përshëndetje, botë". Në Rust, një skedar main.rs të paktën mund të përmbajë diçka aq të thjeshtë sa një funksion main që shtyp një varg në ekran.

Fjala kyçe fn tregon që po përcaktojmë një funksion, dhe main Kjo është pika hyrëse e programit. Blloku i kodit të funksionit futet brenda kllapave të dredhura. Për të shkruar në konsolë, përdorni makro println!, i cili pranon një literal string (ose një shabllon me faqeshënues) dhe e dërgon atë në daljen standarde që përfundon me një karakter rreshti të ri.

Nëse kompiloni direkt me rustc main.rs, do të merrni një skedar binar të ekzekutueshëm (për shembull, main o main.exe (në varësi të sistemit). Kur ta ekzekutoni, do ta shihni mesazhin në terminal. Por mënyra idiomatike për të punuar me Rust është t'i lini Cargo-s të marrë drejtimin e projektit.

me cargo new nombre_proyecto Një strukturë dosjesh krijohet automatikisht me një src/main.rs tashmë të përgatitur me një "Përshëndetje, botë" dhe një skedar Cargo.toml i cili përmban meta të dhëna dhe varësi të ardhshme. Nga aty, cargo run kompiloni dhe ekzekutoni skedarin binardhe rikompilohet vetëm kur zbulon ndryshime.

Kjo mënyrë pune jo vetëm që është e përshtatshme, por ju mëson të përdorni ekosistemin standard të Rust që nga fillimi, gjë që është shumë e dobishme kur filloni të shtoni arka për paralelizëm, rrjetëzim, testim ose çfarëdo që ju nevojitet.

// Deklarojme funksionin main: pika hyrëse e programit fn main() { // Perdorim makron println! per te printuar tekst ne konsol println!("Pershendetje, bote!"); }

Variablat, ndryshueshmëria dhe llojet themelore të të dhënave

Në Rust, variablat deklarohen me fjalën kyçe let, dhe si parazgjedhje janë të pandryshueshmeMe fjalë të tjera, pasi t'u caktoni atyre një vlerë, nuk mund ta modifikoni atë nëse nuk e deklaroni në mënyrë të qartë si të ndryshueshme me mut.

Pandryshueshmëria si parazgjedhje ndihmon në shmangien e gabimeve të vogla logjike, veçanërisht në programet e njëkohshme ku fije të shumta mund të duan të ndryshojnë të njëjtën vlerë. Nëse keni nevojë ta ndryshoni atë, shkruani diçka si let mut contador = 0;Nga aty mund të ricaktoni vlera të reja në contador.

Ndryshku gjithashtu lejon të ashtuquajturin krijim hijeshMund të deklaroni një variabël të re me të njëjtin emër brenda të njëjtit fushëveprim, duke fshehur atë të mëparshmin. Kjo nuk është e njëjtë me mutacionin, sepse po krijoni një vlerë të re (e cila mund të jetë edhe e një lloji të ndryshëm). Për shembull, mund të konvertoni nga një varg në një numër të plotë duke përdorur të njëjtin emër, për sa kohë që është një deklaratë e re me let.

Sistemi i tipeve të Rust është statik, që do të thotë se Lloji i secilës variabël dihet gjatë kompilimitMegjithatë, përfundimi i tipit është mjaft i fuqishëm: nëse shkruani let x = 5;Kompiluesi supozon se është një i32 Përveç nëse e përcaktoni ndryshe. Mund të shtoni shënime të tilla si let x: i64 = 5; kur doni të jeni të qartë.

Ndër llojet skalare të disponueshme janë numrat e plotë me shenjë dhe pa shenjë (i8, u8, i32, etj.), ato lundruese (f32, f64), Booleanët (bool) dhe karaktere Unicode (char). Këto lloje të thjeshta zakonisht janë të lira për t'u kopjuar dhe shumë prej tyre e zbatojnë tiparin. Copyqë do të thotë se kur i caktoni ose i kaloni një funksioni, ato kopjohen në vend që të zhvendosen.

Vargjet në Rust: &str dhe String

Trajtimi i tekstit në Rust mund të jetë pak konfuz në fillim sepse bën dallimin e qartë midis "feta" zinxhirësh dhe zinxhirë të patentuarDy pjesët kryesore janë &str y String.

Un &str është një copë e zinxhirit të pandryshueshëmNjë pamje e një sekuence bajtesh UTF-8 të ruajtur diku. Shembuj tipikë përfshijnë literal-e si "Hola"të cilat janë të tipit &'static str (Ato ekzistojnë gjatë gjithë jetëgjatësisë së programit dhe janë të integruara në skedarin binar.) Slices nuk i zotërojnë të dhënat; ato vetëm tregojnë drejt tyre.

  Si e ngarkoni saktë kontrolluesin OLED të Nintendo Switch?

String, nga ana tjetër, është një vargu i vet, i ndryshueshëm dhe i vendosur në heapMund të ndryshohet madhësia, të bashkohet, të kalohet midis funksioneve duke zhvendosur vetitë e tij, etj. Shpesh përdoret kur doni të ndërtoni tekst dinamik ose ta ruani atë për një kohë të gjatë brenda strukturave.

Në shumë skenarë do të transformoheni midis njërit dhe tjetrit: për shembull, do të krijoni një String::from("hola") nga një fetëose do të marrësh hua një &str një String duke kaluar referenca te funksionet që kanë nevojë vetëm të lexohen.

Kjo ndarje midis të dhënave të zotëruara dhe të huazuara është thelbësore për menaxhimin e kujtesës dhe shtrihet në pjesën tjetër të gjuhës: koleksionet, strukturat dhe numërimet ndjekin të njëjtat ide se kush i zotëron dhe kush vetëm shikon.

Funksionet, rrjedha e kontrollit dhe komentet

Funksionet në Rust përcaktohen me fn dhe lejojnë që programi të organizohet në njësi logjike të ripërdorshme. Çdo funksion specifikon lloji i parametrave të tij dhe lloji i kthimit të tij duke ndjekur një shigjetë ->Nëse nuk kthen asgjë kuptimplotë, supozohet lloji unitar. ().

Një detaj i rëndësishëm është se shprehja e fundit në një funksion (ose çdo bllok) pa pikëpresje merret si vlerë e kthyer implicite. Mund të përdorni return për kthime të hershmePor në kodin idiomatik, shpesh thjesht e lini shprehjen përfundimtare pa të. ;.

Fluksi i kontrollit trajtohet me klasikët if/elsesythe loop, while y forNë ndryshk, if Është një shprehje që kthen një vlerëkështu që mund ta përdorni direkt në një letme kusht që degët të kthejnë të njëjtin lloj. Cikle for Ato zakonisht iterojnë mbi diapazone ose iteratorë koleksionesh dhe janë opsioni i rekomanduar në vend të indekseve manuale.

Për të dokumentuar kodin dhe për ta bërë jetën më të lehtë për këdo që vjen më pas (përfshirë edhe veten tuaj pas një muaji), mund të përdorni komentet e rreshtit me // ose blloko me /* ... */Përveç kësaj, Rust ofron komente mbi dokumentacionin me /// të cilat bëhen dokumente të gjeneruara, megjithëse kjo përshtatet më shumë në projekte të mëdha.

Pronësia, huadhënia dhe jetëgjatësia: themeli i sigurisë së kujtesës

Këtu arrijmë në zemër të modelit të kujtesës së Rust-it: sistemi i pronësia, huamarrja dhe jetëgjatësiaKëto rregulla sigurojnë që referencat të jenë gjithmonë të vlefshme dhe që memoria të lirohet në mënyrë të sigurt pa mbeturina të grumbulluara.

Rregullat themelore të pronësisë janë të thjeshta për t'u deklaruar, megjithëse në fillim mund të jenë të vështira për t'u përvetësuar: Çdo vlerë ka një pronar të vetëm.Mund të ketë vetëm një pronar në të njëjtën kohë; dhe kur pronari largohet nga fushëveprimi i tij, vlera shkatërrohet dhe memoria e tij lirohet. Kjo vlen, për shembull, për një String: pas përfundimit të bllokut ku është deklaruar, thirret automatikisht drop gjë që liron memorien e heap-it.

Kur i caktoni një vlerë të duhur një variabli tjetër ose e kaloni atë sipas vlerës në një funksion, vetia zhvendoset. Kjo do të thotë që Variabli origjinal pushon së qeni i vlefshëm pas lëvizjesKjo semantikë lëvizjeje shmang publikimet e dyfishta, sepse nuk ka kurrë dy pronarë që përpiqen të publikojnë të njëjtin burim.

Për të lejuar që pjesë të shumta të programit të kenë akses në të njëjtën vlerë pa ndryshuar pronësinë, Rust prezanton referencat dhe huazimin. Kur huazoni, krijoni një referencë. &T (i pandryshueshëm) ose &mut T (i ndryshueshëm) ndaj vlerës pa transferuar pronësinë. Kredia është e kufizuar nga rregullat e verifikuesit të kredisë., i cili kontrollon që referencat të mos i mbijetojnë të dhënave që tregojnë dhe që qasjet e ndryshueshme dhe të përbashkëta të mos përzihen në mënyrë të rrezikshme.

Rregullat e kredisë mund të përmblidhen si më poshtë: në çdo kohë të caktuar, ju mund të keni ose referenca të shumta të pandryshueshme në një vlerë, ose një referencë e vetme e ndryshueshmePor jo të dyja në të njëjtën kohë. Kjo eliminon kushtet e racës në kujtesën e përbashkët: ose ka shumë lexues, ose ka një shkrues të izoluar; kurrë lexues dhe shkrues të njëkohshëm në të njëjtat të dhëna në të njëjtin çast.

Llojet e përbëra: strukturat, numërimet dhe treguesit inteligjentë

Rust ofron disa mënyra për të grupuar të dhënat e lidhura në struktura më të pasura, duke filluar me strukturatNjë strukturë ju lejon të përcaktoni një lloj të personalizuar me fusha të emërtuara, për shembull një përdorues me email, emër, status aktiviteti dhe numërues hyrjeje.

Për të krijuar një instancë të një strukture, plotësoni të gjitha fushat e saj dhe mund ta shënoni variablin që e përmban atë si të ndryshueshëm për të modifikuar vlerat e tij më vonë. Ekziston gjithashtu sintaksa e përditësimit të strukturës, e cila ju lejon të ndërtoni një instancë të re duke ripërdorur disa fusha nga një ekzistuese. ..otro_struct.

L numërime Ato janë një tjetër shtyllë thelbësore: ato ju lejojnë të përcaktoni një lloj që mund të jetë një nga disa variante të mundshme, secili me të dhënat e veta të shoqëruara ose pa to. Një shembull klasik është një numërim për adresat IP, me një variant. V4 i cili ruan katër oktete dhe një tjetër V6 që ruan një varg me simbolizimin IPv6.

Biblioteka standarde e Rust përfshin dy numërime shumë të rëndësishme: Option<T> y Result<T, E>E para përfaqëson praninë ose mungesën e një vlere (diçkaje ose asgjëje) dhe përdoret për të shmangur treguesit null; e dyta modelon operacionet që mund të kthen një rezultat të saktë ose një gabim, duke kërkuar që trajtimi i gabimeve të jetë i qartë dhe i sigurt.

Për të menaxhuar memorien dinamike dhe për të ndarë të dhëna, Rust ka tregues të zgjuar si Box<T>, i cili zhvendos një vlerë në heap dhe ruan pronësinë unike; Rc<T>, një numërim i përbashkët referencash për mjedise me një fije të vetme; dhe Arc<T>, të ngjashme me Rc por i sigurt për fije të shumëfishta. Përdorimi i tyre në mënyrë korrekte është thelbësor kur kombinohet memoria dinamike me konkurencën.

Ngarkesa dhe Ekosistemi i Arkave

Ngarkesa është ngjitësi që mban të bashkuar ekosistemin Rust: menaxhon kompilimin, varësitë dhe ciklin jetësor të projektitÇdo projekt ka një skedar Cargo.toml i cili vepron si një manifest, duke deklaruar emrin, versionin, botimin gjuhësor dhe varësitë e jashtme.

  Si të lidheni me një shembull EC2 në AWS me SSH

seksion Ky skedar ju lejon të listoni arkat e palëve të treta me versionet e tyre. Kur e ekzekutoni cargo build o cargo runCargo i shkarkon automatikisht këto arka nga crates.io, i kompilon dhe i lidh me projektin tuaj. Është kaq e lehtë të shtosh, për shembull, gjeneratorë numrash të rastësishëm, korniza web ose biblioteka kriptografike.

Ndër komandat më të zakonshme janë cargo new për të filluar projekte binare o cargo new --lib për bibliotekat; cargo build për të kompiluar në modalitetin e debugimit; cargo build --release për të marrë një version të optimizuar dhe të orientuar drejt prodhimit; dhe cargo test për të ekzekutuar baterinë e testeve.

cargo check Meriton përmendje të veçantë: kompilon kodin në një pikë të ndërmjetme pa gjeneruar një skedar binar, gjë që e bën atë të jetë shumë i shpejtë në zbulimin e gabimeve të kompilimitËshtë perfekt për iterim të shpejtë ndërsa kontrolluesi i huazimit nxjerr në pah problemet me vetitë, referencat dhe jetëgjatësinë.

Falë këtij ekosistemi, është e zakonshme të strukturoni projektet tuaja si kuti të vogla dhe të përcaktuara mirë, duke ndarë kodin midis tyre dhe duke ripërdorur zgjidhjet e krijuara nga komuniteti. Për programim të përparuar të bashkëveprimit, për shembull, do të keni kuti si Tokio për programim asinkron ose crossbeam për struktura të dhënash të njëkohshme me performancë të lartë.

Konkurrenca në Rust: fijet, mutekset, kanalet dhe atomet

Njëkohshmëria është një nga arsyet pse Rust po ngjall kaq shumë interes: ju lejon të përfitoni nga procesorët shumëbërthamorë. pa rënë në gabimet tipike të fijeve dhe kujtesës së përbashkëtNëse kjo është hera juaj e parë që trajtoni këto tema, është e dobishme të bëni dallimin midis disa koncepteve.

Konkurrenca përfshin ekzekutimin e detyrave të shumëfishta që mbivendosen në kohë, qoftë në një ose në shumë bërthama. Në Rust, ju mund të krijoni fije të sistemit për të kryer punë paralelisht, dhe gjuha ju udhëzon për të siguruar që ndarja e të dhënave midis tyre është e sigurt. Një gabim klasik është kushti i garës, ku dy fije qasje dhe modifikojnë të dhënat njëkohësisht, dhe rezultati varet nga rendi i ekzekutimit - diçka shumë e vështirë për t'u debuguar.

Për të koordinuar aksesin në të dhënat e përbashkëta, Rust mbështetet në primitivë të tillë si mutextë cilat garantojnë përjashtim të ndërsjellë: vetëm një fije mund të hyjë në seksionin kritik në të njëjtën kohë. Në kombinim me Arc<T> Për të ndarë pronësinë midis fijeve, është e mundur të ndërtohen struktura të përbashkëta të të dhënave që përputhen me rregullat e pronësisë dhe huazimit.

Një formë tjetër e zakonshme e komunikimit të ndërthurur, e inkurajuar shumë në Rust, është kalimi i mesazheve duke përdorur CanalesNjë kanal ka një skaj dërgues dhe një skaj marrës; fijet kalojnë mesazhe (vlera) përmes tij, gjë që zvogëlon përdorimin e memories së përbashkët të ndryshueshme dhe thjeshton arsyetimin rreth gjendjes së sistemit.

Kur hulumtoni më thellë në paralelizmin e nivelit të ulët, shfaqen këto: llojet atomikeVariablat atomike aksesohen nëpërmjet operacioneve që janë të pandashme nga perspektiva e fijeve. Kjo lejon zbatimin e numëruesve të përbashkët, flamujve të gjendjes, radhëve pa bllokim dhe më shumë. Zotërimi i variablave atomike kërkon kuptimin e modeleve të memories dhe komandave të aksesit, kështu që shumë zhvillues preferojnë të fillojnë me mutexes dhe kanale përpara se të thellohen në këto detaje.

Hapat e parë dhe burimet për të mësuar konkurencën dhe atomiken

Nëse po hyn në arenë pa përvojë paraprake, veprimi më i mençur është ndërtoni një bazë të fortë të koncepteve të përgjithshme përpara se të trajtohen mjete të avancuara si llojet atomike të Rust-it. Libra si "Programimi i Rust-it" ofrojnë një hyrje graduale, por është normale që veprat e përqendruara në llojet dhe kyçjet atomike të duken të dendura në fillim.

Për lehtësi më të madhe, këshillohet që së pari të njiheni me Fijet tradicionale, përjashtimi i ndërsjellë dhe kalimi i mesazheve në Rust. Luaj me shembuj të std::thread, std::sync::Mutex, std::sync::Arc dhe kanalet e std::sync::mpsc Ju ndihmon të kuptoni se si ju udhëzon përpiluesi dhe cilat gabime shmang ai.

Paralelisht, rekomandohet fuqimisht të rishikohen burimet hyrëse mbi konkurencën në përgjithësi, edhe nëse ato nuk janë të përqendruara te Rust: të kuptuarit se cilat janë kushtet e garës, çfarë do të thotë bllokimi, çfarë nënkupton memoria e përbashkët kundrejt kalimit të mesazheve dhe si përdoren kyçjet. Sapo këto koncepte të bëhen të natyrshme për ty, fizika atomike pushon së qeni "magji e zezë". dhe ato bëhen thjesht një mjet tjetër, vetëm se një shumë delikat.

Kur të ktheheni te tekstet më të avancuara rreth atomeve dhe bravave në Rust, do të jetë shumë më e lehtë të ndiqni arsyetimin nëse e kuptoni tashmë se çfarë problemi po përpiqet të zgjidhë secili konstrukt: nga një numërues i thjeshtë i sigurt për fijet te strukturat pa brava që minimizojnë grindjen.

Në fund të fundit, Rust ofron si primitivë të nivelit të lartë ashtu edhe mjete të nivelit shumë të ulët, dhe çelësi është që gjithmonë të zgjidhni nivelin më të sigurt të abstraksionit që zgjidh problemin tuaj, duke iu drejtuar kodit atomik. unsafe vetëm kur ajo vërtet shton vlerë dhe ju i kuptoni plotësisht implikimet e saj.

I gjithë ky ekosistem i llojeve, pronësisë, huazimit, arkave, mjeteve dhe primitivëve të njëkohësisë kombinohet për të ofruar një gjuhë në të cilën mund të shkruhet. softuer i shpejtë, i fuqishëm dhe i mirëmbajturKjo minimizon shumë lloje gabimesh që historikisht kanë pllakosur programimin e sistemeve. Ndërsa praktikoni me projekte të vogla, ushtrime si Rustlings dhe dokumentacion zyrtar, këto koncepte do të kalojnë nga duken si rregulla të rrepta në një aleat që ju paralajmëron përpara se problemi të arrijë në prodhim.

Hyrje në gjuhën Rust me shembuj-0
Artikuj të ngjashëm:
Hyrje e plotë në Rust: Një udhëzues praktik për fillestarët me shembuj