diff --git a/src/contents/6-tervezes.tex b/src/contents/6-tervezes.tex index 2bf16ce853da644ab5011e651825b89e0fa2c66c..37b2c6b565ed5e716b521221c21b5db3213de73f 100644 --- a/src/contents/6-tervezes.tex +++ b/src/contents/6-tervezes.tex @@ -184,6 +184,88 @@ megoldásoknak. \paragraph{} A Rust nyelv ötlete egy Mozilla-nál dolgozó fejlesztő fejéből pattant ki, amikor egy liftbe beszállt és az elromlott, hibás szoftver miatt. +Kiábrándítónak tartotta, hogy a modern információs technológia korában még +mindig előfordulhatnak ilyenek; helytelen szoftver futásából keletkező hibák. +\cite{rust-history} Ahogy \aref{inf-bizt}. fejezetben is láttuk, a legtöbb +hiba helytelen memóriakezelésből származik. A nyelv megálmodója azt a célt +tűzte ki a Rust számára, hogy a memóriakezelést tegye biztossá, biztonságossá +és egyértelművé egy új megközelítéssel. \textsl{``A programozási nyelvek + tervezésénél a magas szintű ergonómia és az alacsony szintű vezérlés gyakran + ellentétben áll egymással; a Rust szembemegy ezzel a konfliktussal.''} +\cite{rust-book} -- írja a nyelv hivatalos dokumentációja. + +A memóriakezelés programozási nyelvek körében általában futásidőben vagy +fordítási időben történik (pontosabban a fejlesztőre van bízva -- allokálás +és deallokálás saját kezűleg történik). Az előbbit az úgynevezett ``garbage +collector'' végzi, ami tipikusan az egyes memóriaterületekre mutatott +referenciák számát figyelve dönti el, hogy a mutatott memóriaterületet fel +lehet szabadítani vagy sem -- használatban van-e még vagy már nem. Ezzel a +feljesztő válláról leveszi a memória kezelésének terhét, hiszen azt a program +futtatókörnyezete teszi helyette. Ennek a megközelítésnek az a hátránya, hogy +több memóriát használ, mint amennyire szükség lenne. Egy embedded rendszer +kereteiben ez kritikus, ezért zártam ki a választáskor az ilyen nyelveket. Az +utóbbi eset; a fordítási időben való memóriakezelés már nem ilyen triviálisan +megoldható kérdés. A Rust is egy ilyen nyelv, és ehhez különböző megkötéseket és +módszertanokat vet be. + +Az egyik alapvető különbség más statikus típusú, procedurális és imperatív +nyelvektől, hogy minden változó első hozzárendelése után az nem megváltoztatható +-- a változó ekkor ``immutable''. Többszöri hozzárendelés esetén a program nem +fordul, a fordító hibaként jelzi, hogy az immutable. Ha szükséges a változó +értékét változtatni a program élete során, akkor azt a \verb|mut| kulcsszóval +lehetséges ``mutable'' változóvá tenni. Ekkor megengedett a többszöri +hozzárendelés, de ez más megkötésekkel fog járni, ha a referenciát hozunk +létre a mutable változóra. \cite{rust-book} Minden változóra lehet referenciát +létrehozni, de egyszerre csak egy referencia létezhet egy változóra. Továbbá +a referenciák maguk is lehetnek immutable vagy mutable referenciák, és rájuk +is egyéb korlátozások vannak helyezve. Ezek a szabályok ugyanúgy a fordítás +idejében kerülnek ellenőrzésre. \cite{rust-book} Jól látható, hogy a helytelen +használatból fakadó hibaforrások sokkal hamarabb és kontrolláltabb módon +felszínelhetőek, mint egy futásidő alatt ellenőrzött módon. + +Minden változónak van egy tulajdonosa és tulajdonosból kizárólag egyetlen +lehet. Amikor a tulajdonos kilép a hatóköréből, akkor a változó értéke is +el lesz dobva. Ha az a heap-en volt, akkor itt történik a deallokáció. Ez +az ``ownership'' fogalma a Rust-ban. Ennek segítségével tudja garantálni +a memóriabiztonságot fordítási időben, egy futás idejű garbage collector +használata nélkül. \cite{rust-book} Furcsa lehet első látásra, hogy minden +változónak egyetlen tulajdonosa lehet, amiből azt a következtetést lehet +levonni, hogy így lehetetlen konkurrens hozzáférést implementálni egy több szálú +programban. Ahhoz, hogy ez lehetséges legyen, a Rust bevezeti az ``interior +mutability'' paradigmáját. A standard library tartalmaz olyan építőkocka jellegű +adattípusokat, melyek enkapszulálják a mutable memóriaterületet. Hívó fél +számára elegendő egy immutable reference az adattípusra, mégis van lehetőség +a belső memória tartalmának változtatására. A következő bekezdésben ismertetem +ez hogyan lehetséges. Az ilyen építőkocka adattípusokkal vannak implementálva +például a mutexek, read-write lock-ok, atomic reference counted (Arc) pointer. +\cite{rust-book} + +Alapesetben nincsenek nyers pointer típusok, amivel az ownership szigorú +modelljét ki lehetne kerülni. Felmerül a kérdés: így hogyan lehet alapvető +adatszerkezeteket optimálisan megvalósítani a nyelvben? Emiatt létezik az +úgynevezett ``unsafe Rust'', melynek célja, hogy mégis tudjunk saját kezűleg +optimális, manuálisan memóriakezelt kódot írni. Ez továbbra is megkötésekkel +jár, de sokkal több kontrollt áthelyez a programozóra (egyben felelősséget +is), de ennek árán nem tud memóriabiztosságot garantálni a fordító -- +ezért ``unsafe''. Unsafe Rust kereteiben léteznek nyers pointer típusok, és +megengedett egy pointer dereferenciája. Így egy éles vonalat tudunk húzni egy +adatszerkezet belső implementációja és az azt használó fél között. Ez úton +lehetséges az interior mutability is. A belső implementációt jól optimizált +módon, unsafe kóddal végezhetjük, és az adatszerkezetet használó félnek nincs +szüksége onnantól kezdve unsafe kódot írnia. \cite{rust-book} Az unsafe kód +szintaktikailag ugyanúgy Rust forráskód, csak egy \verb|unsafe| kulcsszóval +nyitott kódblokkba kell helyezni, amivel a fordító felé jelezzük, hogy itt +szeretnénk úgymond átvenni a totál irányítást. + +A dokumentáció által ajánlott az unsafe kód írását kerülni egy felhasználói +alkalmazás keretében, illetve ha komolyan szeretnénk venni a Rust +memóriagaranciáját, akkor ésszerű döntés. Igyekszem ezt betartani a központi +egység firmware írásában, kivéve ha más módon nem implementálható valami, vagy +ha optimálisnak látom annak használatát. Az utóbbi esetében jól dokumentálom +annak okát és helyes használatát. Ezzel a hozzáállással a szoftverbiztonság +garanciáját a nyelvi elemekre és a fordítóra helyezem át ahol csak lehet, +csökketve az emberi hibából fakadó helytelenségeket. + \subsection{MQTT protokoll} diff --git a/src/hivatkozasok.bib b/src/hivatkozasok.bib index 7effb22970487a12af6cc38b88e32a510db6102f..eb51d18cfde4abc5cc04bddd7e36bc9f8480e4e0 100644 --- a/src/hivatkozasok.bib +++ b/src/hivatkozasok.bib @@ -533,3 +533,15 @@ urldate = {2025-04-22}, }, urldate = {2025-04-24}, } + +@online{rust-history, + title = {How Rust went from a side project to the world’s most-loved + programming language}, + organization = {MIT Technology Review}, + author = {Clive THompson}, + date = {2023-02-14}, + url = { + https://www.technologyreview.com/2023/02/14/1067869/rust-worlds-fastest-growing-programming-language/ + }, + urldate = {2025-04-25}, +}