Rust oktatóanyag: Memóriabiztonság és párhuzamosság

Utolsó frissítés: 04/12/2025
Szerző: Izsák
  • A Rust a tulajdonjog, a kölcsönzés és az élettartam alapján biztosítja a memória biztonságát fordításkor, szemétgyűjtés használata nélkül.
  • A típusrendszer és az aliasolási szabályok lehetővé teszik az egyidejűséget adatversenyek nélkül mutexek, csatornák és intelligens mutatók használatával.
  • A Cargo, a crates.io és az aktív ökoszisztéma leegyszerűsíti a függőségek kezelését, fordítását, tesztelését és telepítését.
  • A struktúrák, felsorolások, opciók és eredmények megértése kulcsfontosságú a hibák kezeléséhez és a biztonságos adatok modellezéséhez egyidejű alkalmazásokban.

C programozási nyelv vs. Rust: előnyök és hátrányok

A rozsda egyike azoknak a nyelveknek, amelyek Minden rendszerfejlesztő újra és újra ezt hallja.Olyan gyors, mint a C és a C++, de szinte megszállottan a memóriabiztonságra és a jól végrehajtott párhuzamos működésre összpontosít. Ez nem csak üres marketing: a felépítése a fordítóprogram azon alapul, hogy fordítási időben észlelje a hibákat – olyan hibákat, amelyeket más nyelveken csak akkor látunk, amikor a rendszer már éles környezetben van... vagy amikor összeomlik.

Ha érdekli a megértés Hogyan éri el a Rust a biztonságos memóriát szemétgyűjtés nélkül, és hogyan éri el a párhuzamosságot adatfutások félelme nélkül?Ez az oktatóanyag neked szól. Áttekintünk mindent a nyelv és ökoszisztémájának alapjaitól kezdve a kulcsfogalmakig, mint például a tulajdonjog, a kölcsönzés, az összetett típusok, az olyan eszközök, mint a Cargo, sőt, az atomi típusokat és a zárolást is megvizsgáljuk egy könnyebben hozzáférhető perspektívából azok számára, akik most ismerkednek a párhuzamossággal, mindezt a biztonságra és a teljesítményre összpontosítva.

Rust oktatóanyag: Teljesítmény, memóriabiztonság és párhuzamosság

A Rust egy programozási nyelv programozás általános célú és több paradigmát alkalmazó, kifejezetten erre a célra tervezve alacsony szintű rendszerprogramozáshoz, valamint magas szintű projektekhez, innen operációs rendszerekA játékmotoroktól és böngészőktől a nagy teljesítményű webszolgáltatásokig a Mozillában született, azzal a céllal, hogy javítsa a szoftverbiztonságot, különösen az olyan érzékeny komponensekben, mint a böngészőmotor.

Meghatározó jellemzője, hogy garantálja a memória biztonságát fordítási időben szemétgyűjtő használata nélkül. Ehelyett a Rust egy tulajdonjog-rendszert és egy kölcsönzés-ellenőrzőt alkalmaz, amely nyomon követi az egyes értékek és referenciáik élettartamát. Ez elkerüli a klasszikus problémákat, mint például a lelógó mutatók, a puffer túlcsordulások vagy a memóriaszivárgások, anélkül, hogy automatikus referenciák számlálására vagy szemétgyűjtésre lenne szükség.

Továbbá a Rust úgy lett kialakítva, hogy megkönnyítse biztonságos párhuzamosságA típus- és tulajdonlási modellje megakadályozza a szálak közötti adatversenyeket, legalábbis a biztonságos Rust kód megőrzése mellett. Ez azt jelenti, hogy számos veszélyes helyzetet már fordítási időben észlel, mielőtt egyetlen sor is végrehajtódna.

Mindezen okok miatt a nagyvállalatok, mint például Dropbox, Microsoft, Amazon vagy Google A Rustot infrastruktúrájuk kritikus részein alkalmazzák. És nem véletlen, hogy évek óta vezeti a Stack Overflow-véleményeket, mint a fejlesztők egyik "legkedveltebb" nyelve: a C++ stílusú teljesítményt modern eszközkészlettel (Cargo, crates.io) és egy nagyon aktív közösséggel, az úgynevezett Rustaceans-szel ötvözi.

Alapfogalmak: programozási nyelv, típusok és memória

Mielőtt belemennénk a memóriabiztonság és a párhuzamosság részleteibe, érdemes tisztázni néhány általános fogalmat, amelyek a dokumentumban végig megjelennek. El Tiempo Amikor a Rusttal dolgozunk, különösen, ha más nyelvekről érkezel, vagy csak most kezdesz programozni.

Egy programozási nyelv végső soron az, egy olyan szabály- és struktúrakészlet, amely lehetővé teszi algoritmusok leírását és végrehajtható programokká alakítja őket. A Rust natív gépi kódra fordul a saját fordítóprogramjával. rustcEzért a kapott teljesítmény általában a C és a C++ szintjén van.

A memóriakezelés az a folyamat, amelynek során egy program futás közben memóriablokkokat foglal le és szabadít felAz ezen a területen előforduló hibák gyakran végzetesek: memóriaszivárgások (a fel nem használt memória felszabadításának elmulasztása), adatvesztés a határokon túli írásból, vagy a memória felszabadítás utáni használata. A Rust ezt egy nagyon erős típusrendszerrel és a tulajdonjogra, kölcsönzésre és élettartamra vonatkozó formális szabályokkal kezeli.

A rozsda olyan kifejezéseket is tartalmaz, mint a intelligens típusok és mutatókA típus leírja, hogy egy változó milyen típusú adatokat tárol (egész számok, lebegőpontos számok, karakterláncok, struktúrák stb.), és hogyan lehet azokat manipulálni. Az intelligens mutatók (például Box, Rc y Arc) olyan struktúrák, amelyek memóriacímeket csomagolnak, és extra logikát adnak hozzá az erőforrások biztonságos kezeléséhez, például a megosztott referenciák számlálásához vagy az értékek halomba mozgatásához.

A verseny területén olyan fogalmak, mint a versenyfeltételek, mutexek és csatornák Nélkülözhetetlenné válnak: versenyhelyzet akkor alakul ki, amikor több szál fér hozzá és módosít egy megosztott erőforrást egyidejűleg megfelelő koordináció nélkül; a mutex (kölcsönös kizárás) biztosítja, hogy egyszerre csak egy szál lépjen be a kritikus szakaszba; és a csatornák lehetővé teszik az üzenetek küldését a szálak között a memória közvetlen megosztása nélkül.

Miért érdemes Rustot tanulni: Memóriabiztonság és félelem nélküli párhuzamosság

A rozsda azért szerzett hírnevet, mert kínál A modern programozás három nagyon értékes pilléreTeljesítmény, biztonság és aktuális eszközök. Nézzük meg, miért olyan relevánsak ezek a pontok.

A teljesítményt illetően, Rust közvetlenül natív bináris fájlokká fordul virtuális gép vagy interpreter nélkül. A nulla költségű absztrakciós modell célja annak biztosítása, hogy a magas szintű absztrakciók ne növeljék a futásidejű többletterhelést. Ezért ideális rendszerfejlesztéshez. játék, böngészőösszetevők vagy alacsony késleltetésű mikroszolgáltatások.

A memória biztonsága azon alapul, hogy tulajdonlási és hitelrendszerNincs szemétgyűjtő, de a fordítóprogram pontosan tudja, hogy ki birtokolja az egyes erőforrásokat, mikor nincs rájuk már szükség, és mikor lehet felszabadítani őket. Ez megakadályozza a szivárgásokat, a lelógó mutatókat és számos olyan hibát, amelyek hagyományosan a C és C++ programozást olyan veszélyessé tették.

A verseny területén a Rust azt folytatja, amit általában ún. „félelem nélküli egyidejűség”Maga a típusrendszer megakadályozza, hogy az adatgyökerek biztonságos kódban létezzenek. Ha módosítható adatokat szeretnél megosztani a szálak között, megfelelő primitíveket kell használnod, például Mutex, RwLock o Arc, és a fordítóprogram biztosítja az aliasolási és mutálhatósági szabályok betartását.

  Hogyan fertőtlenítsük a Windowst Malwarebytes segítségével lépésről lépésre

A fejlesztési élményt modern eszközökkel bővítik, mint például a SzállítmányIntegrált csomagkezelővel és build infrastruktúrával, valamint széleskörű könyvtár-ökoszisztémával (crates) rendelkezik, amely az aszinkron hálózatépítéstől (Tokyo) a webes keretrendszerekig (Actix, Rocket, Axum) mindent lefed. Mindezt egy nyílt, termékeny és meglehetősen türelmes közösség támogatja, különösen a kezdők számára.

Telepítés és alapvető eszközök: rustup, rustc és cargo

Az első Rust programok megírásához és futtatásához a szokásos módon telepítjük a hivatalos eszköztárat a következő használatával: rozsdásodás (lásd a Teljes körű bevezetés a Rustba), egy egyszerű telepítő és verziókezelő, amely minden nagyobb operációs rendszeren működik.

Con rozsdásodás Telepítheted, frissítheted és válthatsz a Rust különböző verziói (stable, béta, nightly) között anélkül, hogy bármi is meghibásodna. Egyszerűen menj a hivatalos Rust eszközoldalra, és kövesd a rendszerednek megfelelő lépéseket. A telepítés után a fordító elérhető lesz. rustc, a projektmenedzser cargo és a sajátja rustup benned terminál.

a fordító rustc Ez alakítja át a forráskódot futtatható binárisokká vagy könyvtárakká. Bár közvetlenül is meghívhatod a következővel: parancsok mint rustc main.rsA gyakorlatban szinte mindig a Cargón keresztül fogsz dolgozni, amely a következő hívásokat kezeli: rustc a megfelelő opciókkal.

A munkafolyamat központi eszköze a SzállítmányNéhány paranccsal új projekteket hozhatsz létre, függőségeket kezelhetsz, csomagokat fordíthatsz, futtathatsz, tesztelhetsz és közzétehetsz a crates.io-n. Néhány gyakran használt alapparancs: cargo new, cargo build, cargo run, cargo test y cargo check, amely a kódot a végső futtatható fájl létrehozása nélkül ellenőrzi, ideális a hibák gyors észlelésére.

Ha anélkül szeretnél bütykölni, hogy bármit is telepítenél, Rozsda játszótér (a hivatalos online végrehajtó) és olyan platformok, mint a Replit, lehetővé teszik apró kódrészletek írását és futtatását a böngészőből, ami tökéletes a memóriával és a párhuzamos példákkal való kísérletezéshez anélkül, hogy a teljes környezetet be kellene állítani.

Az első programod: Hello, Rust és az alapvető folyamatábra

A beszélgetés klasszikus kezdési módja bármilyen nyelven a híres „Hello, world” (Helló, világ) felkiáltás. A Rustban egy fájl main.rs a minimum tartalmazhat valami olyan egyszerűt is, mint egy függvény main amely egy karakterláncot ír ki a képernyőre.

A kulcsszó fn azt jelzi, hogy egy függvényt definiálunk, és main Ez a program belépési pontja. A függvény kódblokkja a kapcsos zárójelek közé kerül. A konzolra való íráshoz használd a következőt: makró println!, amely egy karakterlánc literált (vagy egy könyvjelzőkkel ellátott sablont) fogad el, és a szabványos kimenetre küldi, sortörés karakterrel végződve.

Ha közvetlenül fordítasz a következővel: rustc main.rs, akkor egy futtatható bináris fájlt kapsz (például main o main.exe (rendszertől függően). Amikor futtatod, látni fogod az üzenetet a terminálban. De a Rusttal való munka sajátos módja az, hogy a Cargóra bízzuk a projekt vezetését.

Con cargo new nombre_proyecto Egy mappastruktúra automatikusan létrejön egy src/main.rs már előkészítve egy "Hello, world" felirattal és egy fájllal Cargo.toml amely metaadatokat és jövőbeli függőségeket tartalmaz. Innentől kezdve cargo run fordítsd le és futtasd a bináris fájltés csak akkor fordítja újra, ha változásokat észlel.

Ez a munkamódszer nemcsak kényelmes, de segít megszokni a standard Rust ökoszisztéma használatát már a kezdetektől fogva, ami nagyon hasznos, amikor elkezdesz crate-eket hozzáadni párhuzamos működéshez, hálózatépítéshez, teszteléshez vagy bármi máshoz, amire szükséged van.

// Megadjuk a main függvényt: program entry point fn main() { // A println! makróval kiírjuk a szöveget a konzolra println!("Hello, world!"); }

Változók, mutálhatóság és alapvető adattípusok

A Rustban a változókat a kulcsszóval deklaráljuk. let, és alapértelmezés szerint megváltoztathatatlanokMás szóval, ha egyszer értéket rendelsz hozzájuk, akkor azt már nem módosíthatod, hacsak nem deklarálod explicit módon módosíthatóként a mut.

Az alapértelmezett megváltoztathatatlanság segít elkerülni a finom logikai hibákat, különösen párhuzamos programokban, ahol több szál is módosítani szeretné ugyanazt az értéket. Ha módosítani kell, akkor valami ilyesmit írhatsz: let mut contador = 0;Innen új értékeket rendelhet hozzájuk contador.

A rozsda lehetővé teszi az ún. nyomon követésDeklarálhatsz egy új változót ugyanazzal a névvel ugyanazon a hatókörön belül, elrejtve az előzőt. Ez nem ugyanaz, mint a mutáció, mert egy új értéket hozol létre (ami akár más típusú is lehet). Például konvertálhatsz egy karakterláncot egész számmá ugyanazzal a névvel, amennyiben ez egy új deklaráció, amely a következőt használja: let.

A Rust típusrendszere statikus, ami azt jelenti, hogy Az egyes változók típusa a fordításkor ismert.A típuskövetkeztetés azonban meglehetősen hatékony: ha írsz let x = 5;A fordító feltételezi, hogy ez egy i32 Hacsak másképp nem rendelkezel. Hozzáadhatsz jegyzeteket, például let x: i64 = 5; amikor nyíltan akarsz fogalmazni.

Az elérhető skalártípusok között megtalálhatók az előjeles és az előjel nélküli egész számok (i8, u8, i32stb.), az úszók (f32, f64), a Boole-elméleteket (bool) és Unicode karakterek (char). Ezek az egyszerű típusok általában olcsón másolhatók, és sokan megvalósítják a tulajdonságot CopyEz azt jelenti, hogy amikor hozzárendeled vagy átadod őket egy függvénynek, akkor azok áthelyezés helyett másolásra kerülnek.

Karakterláncok Rustban: &str és String

A Rust szövegkezelése elsőre kissé zavaró lehet, mivel egyértelműen különbséget tesz a következők között: lánc „szeletek” és saját láncokA két kulcsfontosságú darab a &str y String.

Un &str egy megváltoztathatatlan lánc szeleteEgy valahol tárolt UTF-8 bájtsorozat nézete. Tipikus példák az olyan literálok, mint a "Hola"amelyek a típusba tartoznak &'static str (Ezek a program teljes élettartama alatt léteznek, és be vannak ágyazva a bináris fájlba.) A szeletek nem birtokolják az adatokat; csak rámutatnak rájuk.

  A tálca alapos testreszabása a Windows 11 rendszerben: Teljes útmutató és speciális tippek

Stringmásrészt viszont egy saját karakterlánc, módosítható és a heapben tároltÁtméretezhető, összefűzhető, függvények között átadható a tulajdonságának áthelyezésével stb. Gyakran használják, ha dinamikus szöveget szeretnénk létrehozni, vagy hosszú távon struktúrákban tárolni.

Sok esetben váltogatni fogsz az egyik és a másik között: például létrehozol egy String::from("hola") egy szeletbőlvagy kölcsönkérsz egyet &str a String olyan függvényekre való hivatkozások átadásával, amelyeknek csak olvasniuk kell.

A saját és a kölcsönzött adatok közötti elkülönítés kulcsfontosságú a memóriakezelés szempontjából, és kiterjed a nyelv többi részére is: a gyűjtemények, struktúrák és felsorolások ugyanazokat az elveket követik, hogy ki birtokolja és ki csak nézi az adatokat.

Függvények, vezérlési folyamat és megjegyzések

A Rust függvényei a következőképpen definiálhatók: fn és lehetővé teszik a program újrafelhasználható logikai egységekbe szervezését. Minden függvény meghatározza a paramétereinek típusa és a visszatérési típusa egy nyíl követése ->Ha semmi értelmeset nem ad vissza, akkor az unitárius típust feltételezi. ().

Fontos részlet, hogy a függvény (vagy bármely blokk) utolsó, pontosvessző nélküli kifejezése implicit visszatérési értékként szolgál. Használhatod. return korai visszaküldés eseténDe az idiomatikus kódban gyakran egyszerűen kihagyod a végső kifejezést. ;.

A vezérlési folyamatot a klasszikusokkal kezelik if/elsehurkok loop, while y forRozsdában, if Ez egy kifejezés, amely értéket ad visszaígy közvetlenül használhatod egy letfeltéve, hogy az ágak ugyanazt a típust adják vissza. Ciklusok for Általában tartományokon vagy gyűjteményiterátorokon keresztül iterálnak, és a manuális indexek helyett ajánlott opciót jelentenek.

A kód dokumentálásához és a következő utána következő ember (beleértve magát is egy hónap múlva) életének megkönnyítéséhez használhatja a következőt: soros megjegyzések // vagy blokkolja /* ... */Ezenkívül a Rust dokumentációs megjegyzéseket is kínál a következőkkel: /// amelyek generált dokumentumokká válnak, bár ez inkább a nagyobb projektekbe illik.

Tulajdonjog, kölcsönzés és élettartam: az emlékezetbiztonság alapjai

Itt érkezünk el Rust memóriamodelljének lényegéhez: a rendszerhez tulajdonjog, kölcsönzés és élettartamEzek a szabályok biztosítják, hogy a hivatkozások mindig érvényesek legyenek, és a memória biztonságosan, szemét felhalmozódása nélkül szabaduljon fel.

A tulajdonlás alapvető szabályai egyszerűen megfogalmazhatók, bár elsőre nehéz lehet őket elsajátítani: Minden értéknek egyetlen tulajdonosa van.Egyszerre csak egy tulajdonos lehet; és amikor a tulajdonos elhagyja a hatókörét, az érték megsemmisül, és a memóriája felszabadul. Ez vonatkozik például egy String: a deklarált blokk befejezése után automatikusan meghívódik drop ami felszabadítja a halom memóriáját.

Amikor egy másik változónak megfelelő értéket rendelsz, vagy értékként adod át egy függvénynek, a tulajdonság áthelyezésre kerül. Ez azt jelenti, hogy az eredeti változó az áthelyezés után érvényét vesztiEz a mozgási szemantika elkerüli a dupla kiadásokat, mivel soha nincs két tulajdonos, aki ugyanazt az erőforrást próbálja kiadni.

Annak érdekében, hogy a program több része is hozzáférhessen ugyanahhoz az értékhez a tulajdonjog megváltoztatása nélkül, a Rust bevezeti a hivatkozásokat és a kölcsönzést. Kölcsönzéskor létrehozol egy hivatkozást. &T (változhatatlan) vagy &mut T (módosítható) az értékre a tulajdonjog átruházása nélkül. A kölcsönt a kölcsönellenőrző szabályai korlátozzák., amely ellenőrzi, hogy a hivatkozások nem élnek-e túl a mutatott adatokon, és hogy a módosítható és megosztott hozzáférések nem keverednek-e veszélyesen.

A kölcsön szabályai a következőképpen foglalhatók össze: bármikor választhat több megváltoztathatatlan hivatkozás egy értékre, vagy egyetlen módosítható hivatkozásDe nem mindkettő egyszerre. Ez kiküszöböli a versenyfeltételeket a megosztott memóriában: vagy sok olvasó van, vagy egyetlen író; soha nem fordul elő, hogy egy időben ugyanazon az adaton olvasók és írók lennének.

Összetett típusok: struktúrák, felsorolások és intelligens mutatók

A Rust számos módszert kínál a kapcsolódó adatok gazdagabb struktúrákba csoportosítására, kezdve a struktúrákEgy struktúra lehetővé teszi egyéni típusok definiálását névvel ellátott mezőkkel, például egy felhasználó e-mail címével, nevével, aktivitási állapotával és bejelentkezési számlálójával.

Egy struktúra egy példányának létrehozásához ki kell tölteni az összes mezőjét, és a változót, amely tartalmazza, módosíthatóként jelölhetjük meg, hogy később módosíthassuk az értékeit. Létezik a struktúra frissítési szintaxis is, amely lehetővé teszi egy új példány létrehozását egy meglévő mezők újrafelhasználásával. ..otro_struct.

sok felsorolások Egy másik lényeges pillért jelentenek: lehetővé teszik egy olyan típus definiálását, amely több lehetséges változat egyike lehet, mindegyikhez saját adatokkal vagy azok nélkül. Klasszikus példa erre az IP-címek enumja, egyetlen változattal. V4 amely négy oktettet és egy másikat tárol V6 amely egy IPv6-jelöléssel ellátott karakterláncot tárol.

A Rust standard könyvtára két nagyon fontos felsorolást tartalmaz: Option<T> y Result<T, E>Az első egy érték (valami vagy semmi) jelenlétét vagy hiányát jelöli, és a null pointerek elkerülésére szolgál; a második olyan műveleteket modellez, amelyek képesek… helyes eredményt vagy hibát ad vissza, megkövetelve, hogy a hibakezelés explicit és biztonságos legyen.

A dinamikus memória kezeléséhez és az adatok megosztásához a Rust intelligens mutatók mint Box<T>, amely egy értéket helyez át a halomba, és egyedi tulajdonjogot tart fenn; Rc<T>, egy megosztott referenciaszám egyszálú környezetekhez; és Arc<T>, hasonló Rc de biztonságos több szál esetén. Helyes használatuk kulcsfontosságú a dinamikus memória és a párhuzamos működés kombinálásakor.

A rakomány és a ládák ökoszisztémája

A rakomány az a ragasztó, ami összetartja a Rust ökoszisztémát: kezeli a fordítást, a függőségeket és a projekt életciklusátMinden projekthez tartozik egy fájl Cargo.toml amely manifesztként működik, deklarálva a nevet, a verziót, a nyelvi kiadást és a külső függőségeket.

  Javítva: Windows 10 belső PCI busz illesztőprogram hibája

rész Ez a fájl lehetővé teszi harmadik féltől származó ládák listázását a verzióikkal együtt. Amikor futtatja a cargo build o cargo runA Cargo automatikusan letölti ezeket a ládákat a crates.io-ról, lefordítja őket, és összekapcsolja a projekteddel. Ilyen egyszerű például véletlenszám-generátorokat, webes keretrendszereket vagy kriptográfiai könyvtárakat hozzáadni.

A leggyakoribb parancsok közé tartozik cargo new bináris projektek elindításához o cargo new --lib könyvtárak számára; cargo build hibakeresési módban fordítható; cargo build --release optimalizált, gyártásorientált verziót kapjunk; és cargo test hogy lefuttassa a tesztek sorozatát.

cargo check Külön említést érdemel: bináris fájl generálása nélkül fordítja le a kódot egy köztes pontig, ami nagyon gyorsan kell észlelni a fordítási hibákatTökéletes a gyors iterációhoz, miközben a kölcsönzés-ellenőrző rámutat a tulajdonságokkal, referenciákkal és élettartamokkal kapcsolatos problémákra.

Ennek az ökoszisztémának köszönhetően gyakori, hogy a projekteket kis, jól definiált ládákként strukturálják, megosztva közöttük a kódot, és újra felhasználva a közösség által létrehozott megoldásokat. A fejlett párhuzamos működéshez például olyan ládák állnak rendelkezésre, mint a Tokio az aszinkron programozáshoz, vagy a crossbeam a nagy teljesítményű párhuzamos adatstruktúrákhoz.

Párhuzamos működés Rustban: szálak, mutexek, csatornák és atomicok

A párhuzamos működés az egyik oka annak, hogy a Rust akkora érdeklődést vált ki: lehetővé teszi a többmagos processzorok előnyeinek kihasználását. anélkül, hogy a szálak és a megosztott memória tipikus hibáiba esnénkHa most először foglalkozol ezekkel a témákkal, hasznos különbséget tenni több fogalom között.

A párhuzamos működés több, időben átfedésben lévő feladat végrehajtását jelenti egy vagy több processzormagon. A Rustban rendszerszálakat hozhat létre párhuzamos munkavégzéshez, és a nyelv végigvezeti Önt azon, hogy az adatmegosztás közöttük biztonságos legyen. Klasszikus hiba a versenyhelyzet, amikor két szál egyszerre fér hozzá az adatokhoz és módosítja azokat, és az eredmény a végrehajtási sorrendtől függ – ezt nagyon nehéz hibakeresni.

A megosztott adatokhoz való hozzáférés koordinálásához a Rust olyan primitívekre támaszkodik, mint például mutexamelyek garantálják a kölcsönös kizárást: egyszerre csak egy szál léphet be a kritikus szakaszba. A következővel kombinálva: Arc<T> A szálak közötti tulajdonjog megosztása érdekében lehetőség van olyan megosztott adatstruktúrák létrehozására, amelyek megfelelnek a tulajdonjog és a kölcsönzés szabályainak.

A szálak közötti kommunikáció egy másik gyakori formája, amelyet a Rust erősen ösztönöz, az üzenetküldés a következő használatával: csatornákEgy csatornának van egy küldő és egy fogadó vége; a szálak üzeneteket (értékeket) továbbítanak rajta keresztül, ami csökkenti a módosítható megosztott memória használatát és leegyszerűsíti a rendszer állapotával kapcsolatos érvelést.

Ha mélyebben belemerülünk az alacsony szintű párhuzamosságba, a következők jelennek meg: atomtípusokAz atomi változókhoz olyan műveleteken keresztül lehet hozzáférni, amelyek szál szempontjából oszthatatlanok. Ez lehetővé teszi megosztott számlálók, állapotjelzők, zárolásmentes sorok és egyebek megvalósítását. Az atomi változók elsajátításához meg kell érteni a memóriamodelleket és a hozzáférési parancsokat, ezért sok fejlesztő inkább a mutexekkel és csatornákkal kezd, mielőtt belemenne ezekbe a részletekbe.

Első lépések és források a párhuzamosság és az atomok elsajátításához

Ha előzetes tapasztalat nélkül lépsz be a pályára, a legbölcsebb lépés az, hogy szilárd alapot teremteni az általános fogalmak alapján mielőtt belevágnánk a Rust atomtípusaihoz hasonló fejlett eszközökbe. Az olyan könyvek, mint a „Rust programozása”, fokozatos bevezetést kínálnak, de normális, hogy az atomtípusokkal és zárakkal foglalkozó művek elsőre sűrőnek tűnnek.

A könnyebb eligazodás érdekében érdemes először megismerkedni a Hagyományos szálak, kölcsönös kizárás és üzenetküldés a Rustban. Játssz a példákkal std::thread, std::sync::Mutex, std::sync::Arc és csatornái std::sync::mpsc Segít megérteni, hogyan vezeti Önt a fordítóprogram, és milyen hibákat kerül el.

Ezzel párhuzamosan erősen ajánlott áttekinteni az egyidejűséggel kapcsolatos bevezető forrásokat általánosságban, még akkor is, ha azok nem a Rustra koncentrálnak: megérteni, hogy mik a versenyfeltételek, mit jelent a blokkolás, mit jelent a megosztott memória az üzenettovábbítással szemben, és hogyan használják a zárakat. Amint ezek a fogalmak természetessé válnak számodra, az atomfizika megszűnik "fekete mágia" lenni. és csak egy újabb eszközzé válnak, csak egy nagyon kényes eszközzé.

Amikor visszatérsz a Rust atomokkal és zárakkal foglalkozó haladóbb szövegeihez, sokkal könnyebb lesz követni az érvelést, ha már érted, hogy az egyes konstrukciók milyen problémát próbálnak megoldani: egy egyszerű szálbiztos számlálótól a zármentes struktúrákig, amelyek minimalizálják a versengést.

Végső soron a Rust magas szintű primitíveket és nagyon alacsony szintű eszközöket is kínál, és a kulcs az, hogy mindig a legbiztonságosabb absztrakciós szintet válasszuk, amely megoldja a problémát, atomi kódhoz folyamodva. unsafe csak akkor, ha valóban értéket képvisel, és teljes mértékben megérted a következményeit.

Ez a típusok, tulajdonjogok, kölcsönzések, ládák, eszközök és párhuzamos működési primitívek ökoszisztémája együttesen egy olyan nyelvet kínál, amelyben írhatunk. gyors, robusztus és karbantartható szoftverEz minimalizálja a rendszerprogramozást történelmileg sújtó számos hibatípust. Ahogy kisebb projektekkel, olyan gyakorlatokkal, mint a Rustlings, és hivatalos dokumentációval gyakorlod, ezek a koncepciók a szigorú szabályoknak tűnőből szövetségessé válnak, akik figyelmeztetnek, mielőtt a probléma elérné az éles környezetet.

Bevezetés a Rust nyelvbe példákkal-0
Kapcsolódó cikk:
Teljes körű bevezetés a rozsdába: Gyakorlati útmutató kezdőknek példákkal