kategória | ||||||||||
|
||||||||||
|
||
Az 1940-es években megjelenő első számítógépekben nem beszélhetünk operációs rendszerről, mivel a gép programozása ki kapcsolókkal és rövidzárak megfelelő átdugdosásával történt.
A programozás lassúsága miatt a következő években kidolgozták a programok gyorsabb bevitelének lehetőségét lyukkártya olvasók formájában, amikor a programot már lyukkártyán lehetett bevinni. Ehhez szükséges volt a számítógéphez egy assembly nyelvet definiálni, amely a legalacsonyabb szintű programozási nyelv lett. Csak a speciális szakértők férhettek hozzá ekkor a gépekhez.
Később kidolgozták a FORTRAN programozási nyelvet, amely már magasabb szintű megoldásokat is tartalmazott. Ekkor már a programozó szemtől szembe került a géppel, mivel tipikusan úgy dolgozott, hogy egy terminálon bejelentkezett a gépre, majd a lyukkártyáit betöltette a kártyaolvasóval. Ha a fordítás sikerült, akkor a kártyalyukasztón megjelentek a lefordított program kártyái, amelyet újra betöltött és végre futtathatta a programját. Ha minden rendben volt, akkor a sornyomtatón megjelentek az eredmények. Ha nem volt ok, akkor általában minden kezdődött elölről máskor, mivel a gépidő rendkívül drága volt, a következő programozó pedig az ajtóban állt. Ezt a fajta feldolgozást Open Shop néven illették.
A számítógép használat hatékonyságának fokozására szükségessé vált az operátorok alkalmazása. Az operátor olyan jól képzett alkalmazott, aki profizmusánál fogva jól tudja kezelni az adott számítógépes környezetet, ezáltal gyorsabban lefuttatta a programokat, kezelte a berendezéseket és az eredményeket a nyomtatóról rendszerezve ki tudta adni a programozóknak. Egy hardvereszköz hibájától nem esett kétségbe, hanem ki tudta javítani vagy legalábbis el tudta hárítani a kisebb akadályokat. Ehhez természetesen a munkáját is jobban kellett szerveznie.
Az operátor összegyűjtötte a programozók által leadott feladatokat (job) és a számítógép erőforrásait legkedvezőbben kihasználva lefuttatta őket, majd az eredményt a nyomtatóval kinyomtatta. Ez a fajta munkaszervezés bezárta az ajtót a programozók előtt (Closed Shop). Még napjainkban is vannak olyan környezetek, ahol a programok futtatása hasonlóan történik.
Az ilyen szervezésnél a feladatokat kártyacsomagok jelentették, és a kártyacsomagok - kötegek - vezérelték a programok futását. Így ezt a munkamódszert kötegelt (Batch) feldolgozásnak hívják.
Az operátor persze nem tökéletes, hibázik és lassú, ezért újra gyorsították a rendszereket. A General Motors egy állandóan a memóriában lévő szoftvert alkalmazott, amit monitornak hívtak. Ez a szoftver kezelte a perifériákat. A lyukkártyák olvasását pedig azzal is gyorsították, hogy az adatokat először mágnesszalagra rögzítették és az eredmény is mágnesszalagon született meg.
Később a lyukkártyák adatait is külön un. satellite számítógépen rögzítették szalagra. Később a programozók maguk gépelték be egy buta kis számítógépen, amelyet terminálnak hívunk.
Az így rögzített szalagot az operátor futtatta.
A mágnesszalag használatának megvolt az előnye, hogy bár az adatok sorosan elérhetők a szalagon is, de a szalaggal vissza lehet állni korábbi pozícióba az operátor közreműködése nélkül, akár programból is.
Ennek megfelelően bizonyos előre lefordított library-k adatait nem kellett újra bevinni a gépbe kártyát vagy a terminálon, hanem szalagról lehetett beolvasni.
Az alacsonyszintű assembly és a magas szintű Fortran mellett megjelentek a számítógép vezérlését és a job-ok futtatását vezérlő parancsnyelvek (command language, command interpreter, job control language).
Az 1960-as évekre a kártyaolvasók lassan kimentek a divatból, már lassúnak bizonyultak, majd a processzorok gyorsulásával egyre inkább a mágnesszalag lett a szűk keresztmetszet.
A kérdés megoldására kitalálták a mágneslemezeket, amelyen a bevitt adatokat és az eredményeket átmeneti ideig tárolni lehet, amíg a program le nem futtatja a programot, illetve a nyomtató ki nem nyomtatja az eredményt. A gyakran használt library-ket is lehetett a mágneslemezen tárolni. A perifériák a processzor közreműködése nélkül, DMA vagy megszakításos technikával kezelték le a kérdést. A mágneslemez gyors és látszólag véletlen elérésű volt. Az ilyen rendszereket SPOOL rendszereknek hívták
("Spooling" technika. A feladatokat várakozási sorba állítjuk és ha egy feladatot elvégzett a rendszer, akkor veszi a következőt.)
A mágneslemezek megjelenésével az operációs rendsze 959b15j rek nem csak egy átmeneti tárolót kaptak és ezáltal az egyes programok sebessége javult, hanem minőségileg új helyzet állt elő. A mágneslemezeken egy időben több program adatai is helyet foglalhatnak, a gyors CPU pedig a rendelkezésre álló munkák közül tud válogatni, ennek megfelelően a processzoridő kihasználtsága is növekedett.
A mágneslemezek azt is szükségessé tették, hogy a lemezeken tárolt állományokat valamilyen struktúrában tárolják, azaz létrejöttek a névvel ellátott fájlok és a különböző fájlrendszerek..
Mivel a mágneslemez nagyságrendekkel gyorsabb adatátvitelt tudott biztosítani, mint a mágnesszalagok, ezért bizonyos esetekben a futó programok eredményeit nem is volt célszerű tárolni szalagon, hiszen a következő feldolgozó program a bemenetét a lemezről vehette. Ez felvetette a mágneslemez kapacitásának növelését.
Mivel a mágneslemez - processzor páros sokkal gyorsabb volt, mint a többi periféria, ezért ameddig a lassú perifériák írással, olvasással voltak elfoglalva, addig a processzornak már lehetett adni "elfoglaltságot" a mágneslemezen várakozó programok végrehajtása tárgyában. Így előfordulhatott, hogy egy program eredményeit kiírta a processzor már lemezre, onnan elindult DMA vagy Interrupt technológiával a szalagra írás, de a processzor már a következő memóriában vagy lemezen lévő program futtatásával volt elfoglalva. Az ilyen rendszereket átlapolt rendszereknek hívjuk.
Egy átlapolt rendszer hatékonysága akkor maximális, amikor a CPU idő és a szükséges periféria idő hosszú távon megegyezik. Ennek az egyetlen módja az volt, hogy növeljük a programok végrehajtása közötti párhuzamosságot, vagyis egy időben több job-ot engedünk szóhoz jutni.
Multitaszkos rendszernek nevezzük azt az operációs rendsze 959b15j rt, amely egy időben több felhasználói program futását teszi lehetővé.
Az új perifériák megjelenése és a többfeladatos rendszerek bevezetése komoly kihívást jelzett a korábban csak monitorprogrammal ellátott rendszerekben.
Az új funkciókat be kellet építeni a felügyelő programba, azaz ki kellett bővíteni a rendszer üzemeltető szoftverét? Az így megjelenő programokat már operációs rendszereknek hívjuk.
Az operációs rendszerek fejlődésének következő lépcsőfoka az interaktív multiprogramozás megjelenése volt. A programok futtatását az eddigi rendszerek jól támogatták, de a programok fejlesztését alig. A lyukkártya és a mágnesszalag volt az elsődleges periféria ezeken a rendszerek, most a terminál lett. A számítógépek emberközeli rendszereké váltak. Ez a megjelenő és elterjedő új típusú perifériáknak, a gyors válaszidőknek és egyéb feltételeknek volt köszönhető.
Multiuseres (több felhasználós) rendszernek hívjuk azt az operációs rendsze 959b15j rt, amelyen egy időben több felhasználó dolgozik.
Az új rendszerek megjelenése új kihívásokat jelentett a felhasználói felületek számára is. Az shell-ek helyett több új funkciókat ellátó rendszereket kellett fejleszteni.
Válaszidő. - A terminál előtt ülő felhasználó számára emberi válaszidőket kellett produkálni.
Időosztás (Time Sharing) - A terminálok előtt ülő és egy időben dolgozó felhasználók között meg kellett osztani a processzoridőt. Az időosztásos rendszerekben úgy osztják meg a processzoridőt, hogy minden folyamat annyi ideig dolgozik, ami a felhasználó részére folyamatos futásnak tűnik. Az időszeletet mindig a teljes processzoridő bizonyos százalékában értelmezhetjük.
A felhasználói felület felhasználóbarát - A terminál előtti felhasználó olyan parancsnyelvet akart, amely minden tekintetben kiszolgálja. Ennek legfőbb eleme a command interpreter (pl. Command.Com). Lehetőség szerint felhasználóbarátnak kell lennie egy ilyen rendszernek.
Felhasználói adminisztráció - A felhasználók bejelentkezéseinek, a jogosultságoknak és az adatokhoz való hozzáférésének a kezelése. A terminálok előtt ülő felhasználók egymás közti kommunikációja.
Valós idejű rendszerek.
Olyan interaktív rendszerek, amelyek egy meghatározott időn belül biztosan válaszolnak a felhasználó kérésére.
Nyilván olyan helyeken célszerű időosztásos rendszereket alkalmazni, ahol fontos a megfelelő időzítés. Ilyenek a szerszámgépek vezérlései, az ipari robotok vezérlőrendszerei, de ilyen lehet a valós idejű multimédiás rendszerek működtető szoftvere. Milyen feltételek kellenek egy valós idejű rendszer működéséhez?
A valós idejű rendszerek számára nagyon fontos, hogy a folyamatok mindig a megfelelő időben kapják meg a működésükhöz szükséges adatokat, erőforrásokat, memóriát, processzoridőt. Ennek megfelelően a hardvert és a szoftvert úgy kell méretezni és megtervezni, hogy ha az össze valós idejű feladat működik, akkor is meglegyenek a szükséges erőforrások.
A valós idejű rendszereknek mindig kell annyi tartalékkal rendelkeznie, hogy egy eseményre a szükséges időn belül válaszolni tudjon.
Manapság, a PC-k világában dominál az interaktivitás, de a nagygépes rendszereknél még megvan a kötegelt feldolgozás jelentősége is.
A személyi számítógépek rohamos terjedése óriási lökést adott az operációs rendsze 959b15j rek fejlődésének. A PC-k sikerüket a DOS robosztus, egyszerű és biztonságos használatának, no meg a BASIC nyelvnek köszönhették. A nagy ellenfél, az Apple computer már kezdetektől a grafikus felhasználói felületet részesítette előnyben. Ennek megfelelően a felhasználási területek eloszlottak a két rendszer között és a mai napig is megvan az elkülönülés.
A 80-as évek első fele után a Microsoft, a PC operációs rendszerének fejlesztője felismerte a grafikus felület jövőjét és már 1985-ben megjelent a Windows 1.01. 87-ben megjelentette a Microsoft Windows 2.0-ás rendszerét, amelyet 1990-re fejlesztettek ki használhatóvá. Ez volt a MS Windows 3.0.
1992-ben megjelent a MS Windows 3.1, amely tarolt a világon és megnyitotta a számítógép felhasználók széles körei számára az "egerészés", és a grafikus felület "boldogságát".
Az Intel processzorok sebességének növekedése és a folyamatos fejlesztés nyomán megjelent újabb Windows verziók már egyre inkább hasonlítanak a középkategóriás gépek operációs rendszereire és a megnövekedett teljesítményt jól kihasználó rendszerekké váltak.
A fejlődés során két alapvető vonal rajzolódott ki. Az otthoni felhasználók vonala, akik a számítógépük használatánál inkább a minden irányban meglévő kompatibilitást és használhatóságot tekintik fontosnak. Számukra a Windows rendszert ajánlja a Microsoft (Windows 95/98/Millenium). A professzionális felhasználók, a munkahelyek számára az 1993 megjelent és azóta folyamatosan fejlődő Windows NT családot ajánlják (Windows NT 3.1, 3.5, 4.0, Windows 2000). Ez utóbbi sorozat már nem akar kompatibilis lenni a DOS-os időkkel, felépítése nagyon hasonlít a nagyobb rendszerek felépítéséhez.
A 90-es évek elején egy Finn diák, Linus Towards szakdolgozatában kifejlesztett egy egyszerű UNIX klón operációs rendszert PC-re, amelynek forráskódját szabadon hozzáférhetővé tette. Ettől kezdve megindult ennek az operációs rendsze 959b15j rnek a fantasztikus fejlődése. Mára azt lehet mondani, hogy teljesen egyenértékű a piacon lévő PC-s UNIX rendszerekkel, sok tekintetben jobb, mint a Windowsos rendszerek. Természetesen a terjedést segíti a világméretű fejlesztőcsapat, ugyanakkor nem lehet megjósolni pontosan, hogy mikor lesz olyan jól és könnyen használható, mint a Windowsos rendszerek.
Az összes UNIX rendszeren általánossá vált a parancssori shell mellett a grafikus felület használata is.
Ahogy a PC-k teljesítménye megközelíti a közepes gépek teljesítményét, úgy veszik át azok szerepeit. Természetesen mindig megmaradnak a különbségek, hiszen a PC-k eleve rendszerükben hordozzák a kompatibilitási hátrányokat.
Az elmúlt évtized a hálózatok és az Internet elterjedésének a kora volt. Ennek megfelelően az operációs rendszerekbe beépültek a megfelelő eszközök a kezelésükre.
Akkor beszélünk multiprocesszoros rendszerről, amikor egy rendszerben kettő vagy több processzor üzemel párhuzamosan. A klasszikus többprocesszoros rendszerekben a processzorok osztozkodnak ugyanazon a memórián, háttértárakon és egyéb perifériákon és az adat- és rendszerbuszon is. Az ilyen rendszereket szorosan csatolt rendszernek is nevezzük.
A fejlesztőket a több processzoros rendszerek komoly kihívások elé állítják, ugyanis meg kell valósítani olyan ütemezési, kommunikációs és szinkronizálási kérdéseket, amelyek 1 processzor esetén nem jelentenek problémákat. A multiprocesszoros hardver, önmagában nem minden esetben jelenti azt, hogy a teljes rendszer multiprocesszoros módban működik. Például a Windows 9x rendszerek nem lehetnek multiprocesszorosak nem tudják kihasználni a második processzort, de a Windows NT 4 multiprocesszoros verziója, a Windows 2000, a Linux újabb verziói, vagy a Novell NetWare 5.xx verziói igen. Az ilyen rendszerek előnyei ugyanakkor sokat nyomnak a latban:
Megnövekszik az átbocsátó képesség. Különösen a processzorigényes feladatok sebessége nő meg ugrásszerűen.
Erőforrásokat lehet megtakarítani, hiszen ha a szűk keresztmetszet a számítási teljesítmény, akkor nem kell mindenáron további perifériákat vásárolni.
Hibatűrő rendszerek. Ha egyik processzor meghibásodik, a másik még mindig elvégzi helyette a biztonsági funkciókat.
Hátrányai:
Megnövekedett adminisztráció
Bonyolultabb, ezért drágább hardver
Bonyolultabb operációs rendszer
Egy multiprocesszoros rendszer lehet:
Szimmetrikus (SMP - Symmetric Multi Processing), amikor a rendszer minden processzora egyenértékű, bármelyik processzor minden felmerült problémát képes kezelni.
Asszimetrikus, amikor egyes processzorok csak egy részterület kiszámításáért felelősek, a processzorok közvetlenül nem vállalják át az egymás feladatait. Az ilyen rendszerekben mindig van egy főnök, amely vezérli a többi berendezés működését.
A multiprocesszoros rendszerek hardvere vagy az operációs rendsze 959b15j r önmagában azt sem határozhatják meg, hogy szimmetrikus vagy aszimmetrikus működésűek, csak a két szint együttesen döntheti el ezt a kérdést is.
Több processzort úgy is össze lehet kapcsolni, hogy minden processzornak saját memóriája, saját perifériái vannak, azaz önállóan működő számítógép. A kapcsolat a gépek között valamiféle kommunikációs csatornán keresztül valósul meg, helyi hálózaton, telefonvonalon keresztül stb. Az ilyen rendszerek tipikus példái a számítógép-hálózatok. A lazán csatolt rendszerek megvalósításának egy érdekes példája a szerverek fürt technológiája, azaz clusterezése, amikor több egyforma operációs rendszert működtető szerver valamilyen nagyon gyors kapcsolatban áll egymással, optikai vagy Fast Ethernet (100Mbit/s) kapcsolattal és az egyes gépek operációs rendszerei a beérkezett felhasználói igényeket elosztják egymás között. Az egyes feladatokat a terhelés és a célszerűség alapján szolgálja ki a megfelelő szerver. A felhasználó viszont csak egy szervert lát! Ha egy ilyen rendszerben egy szerver meghibásodik vagy egyéb ok miatt kiesik, a többi rendszer pár másodperc alatt átvállalja a kieső szerver feladatait, a felhasználó átmeneti várakozáson kívül nem érez semmit. A NetWare 5.x és a Windows 2000 Advanced Server speciális változatai képesek ilyen technikára.
A lazán csatolt rendszerek használatára komoly érveket lehet felsorakoztatni:
Rugalmasság. A rendszerek egyes részei származhatnak más és más gyártótól, optimális lehet az összeállítás.
Erőforrás megosztás. Az különböző adatbázisok, lehetnek különböző számítógépeken, mindig a legmegfelelőbb helyen
Sebességnövekedés. Több számítógép végezheti ugyanazt a feladatot, a feladatok a kevésbé terhelt gépre átirányíthatók.
Megbízhatóság. A szimmetrikus rendszerekben egy gép kiesése pótolható, de aszimmetrikus esetben a speciális feladatokat végző gép kiesése akár a teljes rendszer működését is megzavarhatja.
Kommunikáció. Az összekapcsolt gépek között az adatcsere működhet fájltranszfer, elektronikus levél, vagy más formába is.
Költségcsökkentés. Az elosztott rendszerek kialakításába beleszólnak a költségtényezők is. A drága perifériákat az ilyen rendszerben többen tudják használni
Az elosztott rendszereknél fontos kérdés az erőforrásokhoz való hozzáférés szabályozása. Az ilyen rendszerekben komoly azonosítási és beléptető szoftvereket szokás használni.
Az elosztott rendszereket összekapcsolásuk módja szerint osztályozhatjuk - Teljes vagy részlegesen csatolt rendszereknek.
Az elosztott rendszert alkotó elemek telje- vagy részleges kapcsolatban állhatnak egymással, viszont kapcsolódásuk fizikai és átviteli jellemzőit tekintve lehetnek csillag, gyűrű, busz topológiájúak.
A kapcsolatok szintjeire vonatkozókat a Hálózati ismeretek című előadássorozatban ismerhetitek meg bővebben, csakúgy mint a hálózatokra jellemző hétrétegű ISO/OSI modellt is.
Bár az operációs rendsze 959b15j rek alapszolgáltatásai hasonlóak, de nyilvánvalóan a futtató hardver tulajdonságai azért befolyásolják a szükséges operációs rendszert.
A személyi számítógépek operációs rendszere viszonylag egyszerű volt. Az MS-DOS, vagy korábban a CP/M operációs rendszerek egyfeladatos, egy felhasználós rendszerek voltak. A használandó hardverek köre sem volt valami tágas. A belépéshez nem volt szükséges semmiféle adminisztrációra.
Az MS-DOS esetén a BIOS és Operációs rendszer szolgáltatásait megszakításokon keresztül lehetett elérni. Természetesen ezek a megszakítások szoftver megszakítások, amelyeket a programozó nyugodtan felhasználhatott. Ezeket az operációs rendsze 959b15j reket az ügyesebb programozók viszonylag kevés szakmai ismeretekkel, megfelelő segédkönyvek és leírások birtokában nyugodtan programozhatták. A használt fájlrendszer is inkább az egyszerűséget, mint a rugalmasságot, biztonságot szolgálta (FAT, FAT32)
A közepes rendszerek már támogatják a multitask és a multiuser funkciókat. Alkalmasak lehetnek arra, hogy terminálon keresztül lépjenek be a felhasználók. Ilyenek a UNIX rendszerek és annak PC-s megvalósítása a LINUX is. A közepes rendszerek már gyakran előfordulnak irodákban, fejlesztőüzemekben, stb.
A nagygépes rendszerek iránt manapság újra nagy az érdeklődés. Bár a 90-es években úgy tűnt, hogy minden vállalat kidobja régi nagygépes rendszerét és PC-ket vesz rajta, azokkal intézi ügyvitelét, termelésirányítását, adatfeldolgozását az ezredfordulóra a nagygépes rendszerek megerősödtek, nem utolsósorban a számítógép-hálózatok és az Internet követelményinek megfelelően. Olyan óriási mennyiségű információ keletkezik másodpercenként a világon, hogy annak feldolgozása csak nagy teljesítményű rendszerekkel működhet folyamatosan és biztonságosan. Ha elképzeljük, hogy egy ország lakossági adatainak nyilvántartása ma már természetes követelmény, akkor azt is elmondhatjuk, hogy például Magyarország kb. 10 milliós népességének adatait kezelni, azokat feldolgozni nem elegendő egy PC.
A nagygépes rendszerek természetesen sokféle hardvert kezelnek, távolról is bejelentkezhetnek rájuk terminálon vagy egyéb hálózatokon keresztül. Multiuser, multitaszk rendszerek. A hardverekkel szemben nagyon magas szintű követelmények állnak fent, a rendelkezésre állás, az adatok hozzáférhetősége, megbízhatósága, a rendszer adminisztrációja, a userek adminisztrációja olyan tényezők, amelyek az ilyen rendszereket megkülönböztetik a közepes vagy kisgépes rendszerektől.
A számítástechnika használata során az egyik leggyakrabban használt fogalom a program fogalma. Ezen egy algoritmust megvalósító utasítások sorozatát értjük, amely független attól, hogy milyen nyelven írták vagy milyen módon tároljuk. Abban az esetben, ha egy programot elindítunk, azaz "futtatjuk", a programot már folyamatnak (process, task, job) hívjuk.
Egy program futása során több különböző folyamatot is elindíthat, amelyek esetleg egymástól függetlenül végzik munkájukat, és fejeződnek be. Ebben az esetben a létrehozó folyamatot szülőnek (parent process), a létrejött folyamatot pedig gyereknek (child process) hívjuk.
Mivel multiprogramozott környezetben a processzek száma általában nagyobb, mint a processzorok száma, ezért az egyes folyamatok közötti átkapcsolás során a folyamat pillanatnyi állapotát tárolni és menteni kell. Ezt a leírót, azaz folyamatleíró blokknak (Process Control Block=PCB) hívjuk. Ez tartalmazza a
folyamat azonosítóját
Programszámláló (PC) állását
A folyamat állapotát (aktív, passzív, stb.)
A regiszterek tartalmát
A folyamat memóriaterületeinek adatait
A használt perifériák és fájlok jellemzőit
Szokás a folyamatokat olyan programnak nevezni, amelyiknek PCB-je van.
Ha egy program futása közben olyan folyamatot indít el, amelynek nem szükséges teljes önálló folyamatleíró blokkot kijelölni, mivel adatainak nagy részét ugyanazon a memóriaterületen tartja, mit az őt létrehozó folyamat, és fájlkezelés, perifériái is a létrehozóéval egyeznek meg, akkor a folyamatra a szál (thread) kifejezést használjuk.
Szálak közötti átkapcsolás sokkal gyorsabb, mint a folyamatok között, mivel kevesebb adatot kell tárolni, elmenteni.
Erőforrásnak nevezünk minden olyan dolgot, amely egy folyamat futásához szükséges lehet. Alapvető erőforrások a memória, processzoridő. További, általában szükséges erőforrások aki- és bemenetre használt perifériák, illetve fájlok.
Amikor egy folyamat használ egy erőforrást, akkor azt mondjuk, hogy lefoglalta, amikor befejezte az erőforrás használatát, akkor az bezárja vagy felszabadítja.
Amikor egy erőforrást a folyamatok egymástól elvehetik, akkor elvehetőnek (preemptive) mondjuk azt. Erre példa a processzoridő vagy memória, mivel az operációs rendsze 959b15j r bármikor rendelkezik vele.
Más esetekben a folyamattól csak akkor lehet elvenni egy erőforrást, amikor befejezte vele tevékenységét. Ekkor nem elvehető (non preemptive). Ilyen eset a megnyitott fájlok esete.
Azt is mondhatjuk, hogy a preemptív erőforrásokkal az operációs rendsze 959b15j r szabadon rendelkezik, míg a non preemptív erőforrásokat károsodás vagy adatvesztés nélkül csak az éppen használó folyamat adhat át másnak.
Természetesen kritikus helyzetben az operációs rendsze 959b15j rnek képesnek kell lennie az erőforrások akár erőszakos felszabadítására is. Az operációs rendszerek egyfajta megközelítése ez alapján:
Olyan folyamatok csoportja, amely gondoskodik a felhasználói folyamatok közötti erőforrás elosztásról
A fenti megfogalmazás egyúttal azt is jelenti, hogy a felhasználói folyamatoknak nem kell foglalkozni az erőforrások kezelésével - azaz az operációs rendsze 959b15j r kényelmes felhasználói környezetet biztosít.
Az eddigiek alapján világos, hogy az operációs rendsze 959b15j rnek van egy olyan része, amely közvetlenül a hardverrel áll kapcsolatban és van olyan része is, amely a felhasználói programokkal kommunikál közvetlenül. A operációs rendszernek azokat a programjait, amelyek a hardver és a felhasználói programok között helyezkednek el, hívjuk rendszermagnak, kernelnek.
A kernel önmagában sem alkot általában monolitikus egységet, ugyanis akkor egy új hardver megjelenése például újraíratná az egész kernelt. Belső rétegei vannak.
Védelem a felhasználói programok egymással való interferenciájától.
Rendszerhívások kezelése, és válaszok a felhasználói programok felé
Felhasználói folyamatok kiszolgálása
Programok fejlesztésének támogatása
Processzor, memória és fájlkezelés.
A legalacsonyabb szint a device driverek és a megszakítás-kezelők szintje
A kernel folyamatai a számítógép indulásakor töltődnek be a memóriába és a leállításig működnek is.
Egy átlagos környezetben működő számítógép esetén a kernelben tartózkodik legtöbbet a számítógép, a processzoridő 90-98%-át, ezért nagyon fontos, hogy a kernel működése nagyon gyors legyen. A mai modern processzorok éppen ezért hardveresen is támogatják a kernel működését, ilyenkor egy utasítás hatására kernel módba (privilegizált mód, system mód, stb.) kapcsolódnak és ekkor több mindent tudnak kezelni, mint a felhasználói programok, amelyek a felhasználói mód szolgáltatásait használják. A két üzemmód közötti átkapcsolás speciális rendszerhívások során jön létre, amelyekkel a felhasználói program tudatja az erőforrásigényét a kernellel, amely a rendszerhíváshoz tartozó speciális üzemmóddal válaszol.
Egyes processzorok esetén több egymás feletti prioritással bíró üzemmód is létezik. (Az Intel processzoroknál ezeket az üzemmódokat a ring 0, ring 1, .... ring 255 névvel illetik.) At operációs rendszer minden process indulásakor eldönti, hogy az melyik ring-ben fog futni. A magasabb prioritású processzek bármikor megszakíthatják az alacsonyabb prioritású processzek futását, de az alacsonyabb prioritású process nem teheti meg magasabb prioritású processzel. A kernel mód általában magas vagy a legmagasabb szintű prioritással bír.
A rendszerhívás PC-k esetén leggyakrabban bizonyos szoftveres megszakításokon keresztül zajlik le. Ez a processzorok esetén általában egy speciális utasítás, amely szoftveres megszakítást hoz létre a programban. A szoftveres megszakítás hasonlóan zajlik le, mint a hardveres megszakítás, ezért itt a kettőt nem részletezzük külön.
A rendszerhívás folyamat az alábbiak szerint zajlik le:
A felhasználói folyamat paraméterei elmentődnek (pl. Stack-be)
A megszakítás sorszáma alapján egy táblázatból vett címre, a kernel megfelelő pontjára ugrik a vezérlés.
A paraméterek a stacken, a processzor regiszterein vagy egy erre a célra kijelölt memóriaterületen keresztül átadódnak.
A processzor kernel módba kapcsol át.
A megfelelő rendszerfolyamat elindul és végrehajtja a kívánt feladatot
A válaszok, eredmények, hibakódok a stacken, regisztereken vagy a kijelölt memóriaterületeken keresztül visszaadódik
A processzor visszakapcsol felhasználói módba
A megszakított folymat megkapja a vezérlést.
A megszakítások között általában léteznek prioritások. A szoftver megszakításoknak a legalacsonyabb a prioritásuk, azaz bármilyen hardver megszakítás előnyt élvez velük szemben. A következő prioritási szint a hardver-megszakítási szint. A hardver megszakításokat is félredobhatja a processzor, a kivételkezelésnél (hibakezelés, pl. 0-val való osztás, stb...) A legmagasabb prioritása a trap-nek (csapda) van. A debugger programok alkalmazzák a programok hibáinak kiderítésénél.
Az operációs rendszereket alkotó szoftverek két fő részre oszthatók:: Kernel, Shell
Azok a programok, amelyek a perifériákat, a hardvert kezelik és általában minden olyan funkciót ellát, ami nem kapcsolódik közvetlenül a felhasználókhoz. Részletesen:
Eszközkezelők, (Device Driver) - Perifériakezelő szoftverek. Ezek segítségével a felhasználói programok számára biztosítani lehet a perifériafüggetlenség elvét, azaz a program nem tudja, de nem is érdekli, hogy milyen periféria felhasználásával fut.
Megszakítások kezelése (Interrupt Handling) - A korábbiakban már foglalkoztunk vele.
Rendszerhívások kezelése (System Calls) - A felhasználói programok rendszerhívásait kezeli, és kiszolgálja.
Erőforrás-kezelés (Resource Management) - Erőforrásnak hívunk minden olyan szoftver vagy hardver komponenst, amelyet a felhasználói programok futás közben igénybe vesznek (pl. Perifériák).
Processzor ütemezés (CPU Scheduling) A processzorok futásának biztosításához szükséges processzoridőt biztosítja.
Memóriakezelés (Memory Management) - Biztosítja, a programok futásához megfelelő memóriaterületet, futás közben biztosítja, hogy a programok egymás területére ne írjanak, és ha a program befejezi futását, akkor felszabadítja az elfoglalt memóriát. Biztosítja, hogy a programok ne csak egy adott memóriaterületen futhassanak, hanem áthelyezhetők legyenek.
Állomány- és fájlkezelés (Fájl and Disk Management) - Kezeli a lemezeken lévő fájlok tárolását, kezelését, a fájlrendszert.
Egyes operációs rendszerek olyan mértékig magukra vállalják a hardver kezelését, hogy egyes esetekben teljesen elfedik a felhasználói programok, sőt egyes operációs rendszer komponensek előtt is. Felmerül a kérdés, hogy ha egy tipizált felületen futnak a felhasználói programok, akkor vajon az operációs rendsze 959b15j rt, vagy annak legalábbis a felhasználói programok számára látható részt nem lehetne-e kicserélni? Van-e lehetőség egy operációs rendszerben más operációs rendszerek alatt futó programok használatára?
Vannak olyan operációs rendszerek, ahol a felhasználói programok rendszerhívásokkal, közvetlen hardver kezeléssel is kezelik az erőforrásokat. Nyilván az ilyen rendszerek csak egy felhasználós és egy taszkos rendszerek lehetnek csak. Erre példa az MS-DOS. Az MS-DOS/Windows 3.1 alatt futó rendszerek az elképzelhető összes módon kezelik a hardvert, közvetlenül, közvetve, device drivereken keresztül stb.
Más esetekben az operációs rendszer közvetlen hardverkezelést nem is engedélyez, de bizonyos erőforrások azért elérhetők a gépen. Ilyen a Windows NT.
A legszélsőségesebb eset az, amikor egy felhasználói program egy szoftveresen definiált környezetet vár a futásához. A hardvereket mindig device driveren át kezeli, sőt bizonyos típusú erőforrásokhoz nem is enged hozzáférni. Ilyen a JAVA környezet.
Ha egy operációs rendszeren nem a saját operációs rendszerében használandó programot szeretnénk futtatni, akkor egy olyan folyamatot kell elindítani, ami úgy tesz a felhasználói program számára, mintha Ő a másik operációs rendszer alatt fut. Ez az elindított folyamat egy virtuális számítógép lesz. A felhasználói
program ezen a virtuális gépen keresztül kapja vagy kaphatja meg az erőforrásait. A virtuális gépeket futtató kernelt virtualizáló kernelnek hívjuk. Mikor szükséges a virtualizáló kernel?
Ha egy gépen futó alkalmazásokat teljesen el akarjuk különíteni egymástól.
Ha egy operációs rendszeren más operációs rendszerre íródott programot akarunk indítani.
Ha futtatandó programot más processzorra vagy egyéb hardverre írták.
Ha teljesen hardverfüggetlen programot akarunk futtatni.
Azt hihetné az ember, hogy akkor minden operációs rendszernek virtualizáló üzemmódban kellene mennie. Sajnos vannak hátrányok:
A virtuális gépen keresztül futtatott programok nyilván lassabbak lesznek, mint a natív eléréssel futtatottak, hiszen a processzor számára a virtuális gép csak egy taszkot jelent, aminek ugyanúgy várnia kell a processzoridőre és az egyéb hardverekre, mint bárki másnak.
A processzorok privilegizált üzemmódjait nem mindig lehet összeegyeztetni.
Ha a szimulálandó operációs rendszer maga is tud privilegizáltan működni, akkor az baj.
A lemezkezelés, fájlszerkezet általánosságban nagy-, szinte megoldhatatlan probléma.
Az IBM VM operációs rendszere csak virtuális gépeken keresztül hajlandó futtatni felhasználói programokat -
A Windows NT-n DOS-os vagy Win3.1-es program indításakor először betöltődik egy virtuális gép, amely az MS-DOS 5.0-át emulálja, majd betöltődik a felhasználói program.
A SUN JAVA rendszere teljesen elfedi a hardvert a felhasználói program elől. Amelyik rendszerre megírták a JAVA-t, azon futnak a JAVA-ban írt programok.
Bár a felhasználók elvileg nem találkoznak a kernellel, de a PC-k esetén a felhasználó maga állíthatja be és állítja is be a gépének konfigurációját.
Kézzel: A DOS-ban és a Windows 3.1 alatt ez két (CONFIG.SYS, AUTOEXEC.BAT, továbbá SYSTEM.INI, és WIN.INI fájlok szerkesztését jelentette.)
A Win9x bevezette a Plug and Play technológiát, amely elvileg az automatikus önkonfigurálást jelentette volna.
Létezik félautomata megoldás is, amikor csak külön utasításra adnak ki konfigurációs parancsokat (NetWare Scan telepítéskor).
A DOS konfigurálása a leglátványosabb:
A DOS 20 bites memóriacímzése miatt a memóriakezelés beállítása nagyon fontos és nem elhanyagolható. Az XMS memóriakezelő a HIMEM.SYS és az EMS memóriakezelő az EMM386.EXE, továbbá a különböző memóriaterület lefoglalására vonatkozó parancsok ( LoadHigh, LH, InstallHigh, Install, DOS=HIGH,UMB) régóta foglalkoztatják a rendszergazdákat.
Az adatelérés és átvitel gyorsítására a DOS-ban a BUFFERS=..., FÁJLS=..., SMARTDRV parancsokat kell használni.
Az MS Windows 9x nem nagyon hagyja a fenti paraméterek állítását. Automatikusan állítja be az általa legmegfelelőbbnek tartott értékeket.
A NetWare a fentieknek megfelelő paramétereket a futás során önállóan állítja, de meg vannak adva a minimális és maximális értékek.
Minden operációs rendszer törekszik arra, hogy a programfejlesztők számára olyan fejlesztői környezetet bocsásson rendelkezésre, amely a felhasználói programok rendszerhívásait definiált rendszerhívásokon keresztül fogadja és ugyanilyen módon válaszol is. Ez azt jelenti, hogy a programozó fejlesztés közben beírja programjába azokat a függvényhívásokat, amelyek megvalósítják futási időben a megfelelő rendszerhívásokat. A megfelelő hívások szintaktikájáról, paraméterezésének mikéntjéről az operációs rendsze 959b15j r fejlesztői döntenek, míg a konkrét megvalósításról a fejlesztőeszközt gyártó cégnek kell gondoskodnia.
Egy fejlesztőrendszer programozói felületét (API = Application Programing Interface) az operációs rendszer határozza meg a szolgáltatásain keresztül.
A fejlesztés során a fejlesztő beírja a megfelelő függvényhívásokat a programba, a fordítás során hozzászerkeszti a megfelelő könyvtárakat a LINKER, és az így kapott programot lehet futtatni.
Bár feltételezem, hogy mindenki találkozott már programfordítással, de azért itt röviden összefoglaljuk, hogyan jön létre a forrásszövegből a futtatható program.
A forrásszöveg valamilyen nyelven elkészül, abban hivatkozásokat helyez el a programozó különböző include fájlokra. Ezek a hivatkozások a különböző programozási nyelveken nem feltétlenül forrásszövegű állományra mutatnak (pl. Pascal UNIT-jai), de mutathatnak arra is.
A fordítás során a fejlesztett programok és a beillesztett forráskódra való hivatkozásokból a compiler tárgykódot - Object kódot generál. Ebben a kódban a programozó programsorai már a végeleges gépi sorokat tartalmazzák, viszont az ugró utasításokban még csak szimbolikus címeket szerkeszt be a rendszer. A keletkezett tárgykódhoz a fordításkor megadott és a rendszerben defaultként adott Library-kben lévő függvényekből válogat a rendszer és a második menetben a szerkesztő program (Linker) összeszerkeszti a betölthető programot. Windowsos vagy más grafikus környezetben még a Resource Compiler és linker is lefut, amely a grafikus objektumokat szerkeszti hozzá a kész futtatható programhoz.
Az EXE programokban minden ugróutasítás relatív címet kap, amelyet a betöltő program véglegesít a program betöltése során. Ez azért van így, mert a program fordítása során nem dönthető el, hogy milyen címen fog futni egy program.
A program futtatásakor nem mindig elegendő a futtatható EXE program (DOS-nál esetleg igen), mivel a folyamat olyan rendszerhívásokat hajthat végre, amelyeket az operációs rendsze 959b15j r Dinamikusan csatolt könyvtárakban tartalmaz. Ezek olyan fájlok, amelyek csak akkor töltődnek be a memóriába, ha egy programnak szüksége van rá, és akkor szabadul fel a memóriaterületük, ha már egyik rá hivatkozó process sem fut. Ezeket a fájlokat a Windowsban DLL-nek hívjuk (Dynamic Link Library). Ez a technológia mellesleg más operációs rendszerekben, így az OS/2-ben is tettenérhető.
Az operációs rendszerek mindegyike tartalmaz felhasználói felületet. Ezzel a felülettel találkozik általában a felhasználó. Az operációs rendszerek fejlődése során a felület egyre több funkciót magába olvasztott, és egyre barátságosabb lett, vagy legalábbis próbált azzá válni.
A felhasználói felület feladatai, funkciói:
A parancsnyelv biztosítása, az utasítások végrehajtása
Programok kezelése, programok futtatásához szükséges környezet biztosítása és programindítás
A rendszer állapotának megtekintése, szabályozása
Az operációs rendszer egyéb funkcióinak irányítása (pl. fájlkezelés)
A számítógép kezelése parancsnyelveken keresztül. Ilyen a DOS parancsnyelve vagy a LINUX, UNIX Shell script nyelvei. A parancsnyelvet általában egy értelmező (MS-DOS, command.com) értelmezi, illetve a batch programot (LINUX-ban scriptet) hajtja végre lépésről lépésre. (A parancsnyelvek erősen hasonlítanak a korábbi Job Control Language-ra, kötegelt programfeldolgozás). Megkülönböztetünk belső és külső parancsokat. A belső parancsok mindig a parancsértelmező részeként kerülnek interpretálásra, míg a külső parancsok önállóan léteznek, de gyakran csak az operációs rendszer integráns részeként futtathatók.
A futtatandó program nevének begépelésével vagy egy speciális paranccsal (pl. C-64 vagy NetWare LOAD parancsa) lehet indítani a programot. Egyes esetekben paramétereket vagy kapcsolókat adunk a programokhoz. Néha alkalmassá kell tenni az operációs rendszer környezetét a program futtatásához (pl. Windows PIF fájlok beállításai)
A programok indításánál fontos szempont, hogy általában a programokat az aktuális könyvtárból indítja a rendszer. Ha bonyolult a rendszer vagy el akarjuk kerülni esetleg a több felhasználó miatt a többszörös tárolás problémáját, akkor az alábbi szolgáltatások jöhetnek még szóba:
Link fájlok használata (LINUX, Win9x). Ezekben a rövid leíró fájlokban hivatkozás található az eredeti bináris állományra és a link fájlok futtatásakor az operációs rendsze 959b15j r kiolvassa a fájlból az igazi futtatandó fájl elérési útvonalát és esetleges paramétereit, beállításait. Így indítja el a bináris állományt.
Keresési útvonalak definiálása (DOS, Windows Path parancs). Ennek segítségével az operációs rendszer az aktuális könyvtáron kívül még a megadott keresési útvonalakat nézi végig a bináris állomány indításához.
Láncolt programfuttatás lehetséges. A Batch programokban komoly vezérléseket alkalmazva több program egymás utáni lefutását is lehet szabályozni
Az operációs rendszerek indításakor (MS-DOS AUTOEXEC.BAT, Windows Win.INI LOAD és RUN parancsai, Win9x, NT Registry megfelelő beállítása illetve indítópult.) NETWARE AUTOEXEC.NCF) vagy megadott események bekövetkeztével (Win9x Schedule, NT AT parancs) lehet automatikusan indítani programokat.
A programok futásához szükségesek lehetnek az alábbiak:
Paraméterek. Azok a plusz adatok, amelyek a program működéséhez éppen szükségesek.
Kapcsolók. (switch) A működést pontosítják, illetve az alapértelmezett működést módosítják
Átirányítási adatok. Az alapértelmezett bemenetet fájlból veszi és a kimenetet fájlba írja a futó process.
Környezeti változók beállítása. Az operációs rendszer egyes beállításait lehet így közölni a programokkal (DOS, Windows SET parancs)
A rendszer működési paramétereinek lekérdezése, pl. Memóriaállapot, (DOS, MEM parancs, pl. Linuxnál PS - AUX , NT - Task Manager, Scandisk, Defrag stb.)
Fájlkezelés, könyvtárak kezelése, szervizprogramok futtatása stb. Ezek a szolgáltatások gyakran önállóan futtatható programként vannak jelen az operációs rendsze 959b15j rben, de ettől még a rendszer részeinek tekinthetők, máskor beépülnek a rendszerbe és nem is lehet őket önállóan kezelni.
A grafikus felület gondolata először a nyolcvanas évek elején a Macintosh gépek MacOS nevű operációs rendszerében került előtérbe. Érdekességként megemlíthető, hogy a Microsoft a PC-k esetén csak 1985-ben rukkolt elő az első működő grafikus felülettel, a Windows 1.0-val. Az IBM és a Microsoft sokáig együtt dolgoztak a PC-kre szánt OS/2 projecten, amit végül is az IBM fejezett be és folytat mind a mai napig. A C-64-n s létezett grafikus felület GEOS néven.
A UNIX rendszereken is a nyolcvanas években elkezdődött a grafikus felületek fejlesztése, de ott úgy alakult, hogy az alaprendszer alfanumerikus maradt, csak el lehetett indítani rajta egy grafikus interface-t. Ezt a felületet a UNIX-okon többé-kevésbé szabványosították és elnevezték X-Windows-nak.
Végül is az összes operációs rendszer grafikus felülete (GUI - Graphics User Interface) hasonlóan néz ki, a felület kezelésében alapvetően nem nagyon térnek el. (Érdekes, hogy a grafikus felület az egy taszkos rendszereken nem lett népszerű, betudható talán ez az akkori hardverek teljesítményének is. Másrészt az is meglepő, hogy vannak emberek, akik ma is visszasírják a grafikus felület nélküli időket. )
Az ilyen környezetben a programok futás közben kimenetüket egy szabványos grafikus ablakban jelenítik meg. Az ablak méretét általában lehet változtatni. Az ablaknak három rendszer által megkülönböztetett állapota van.
Az ikonállapot - ekkor a futó folyamatot a grafikus felületen a Desktopon vagy a képernyő egy meghatározott helyén egy ikon jelzi. Ekkor a program fut, csak a kimenet a háttérben marad.
Közbenső állapot - Ekkor a program ablaka általában szabályozható méretben megjelenik a képernyőn. Az ablakot egérrel és billentyűzettel mozgathatom a képernyőn és átméretezhetem.
Teljes képernyős állapot - Ilyenkor a rendelkezésre álló teljes grafikus felületet egyetlen program ablaka foglalja el.
A Windows, az OS/2 és a MacOS esetén a GUI az operációs rendsze 959b15j r szerves része, míg a UNIX és LINUX rendszerek esetén a távolról bejelentkezők a saját rendszerükön indíthatják a grafikus felületet, míg a távoli gép továbbra is karakteres felületen marad. Ennek ellenére az alapkoncepció mind a két rendszertípusban ugyanaz. A GUI feladata, hogy az őt használó folyamatok számára biztosítsa a grafikus bevitel és megjelenítés lehetőségét. Ebből a szempontból a GUI szerverként, míg a programok kliensként viselkednek. A GUI szolgáltat, a program igénybeveszi a szolgáltatást.
A folyamatok és a GUI között üzenetek közlekednek és ezen keresztül tudatja a program az igényét, a szolgáltató pedig így tudatja a programmal, az igényre adott válaszát. A grafikus Interface tehát csak üzenetek esetén tevékenykedik! Hogy is van ez?
Minden futó programnak van egy ablaka, aminek az állapota ikon, ablak vagy teljes képernyő.
A program felhasználója ül a gépe előtt és az egérrel vagy a billentyűzettel foglalatoskodik. Amikor valamilyen billentyűt lenyom vagy az egeret elmozdítja, vagy az egér egyik gombjával kattint valahol, akkor ez egy eseményt generál (event)
Az ablakozó rendszer megállapítja, hogy az esemény melyik ablakhoz kapcsolható (melyik ablaknak milyen grafikus objektumával történt az esemény). Ennek az eseménynek a leírását elküldi az ablakot létrehozó folyamatnak.
Mivel az események gyorsabban is bekövetkezhetnek, mint a feldolgozásuk, ezért az események először a rendszer eseménylistájába, majd miután kiderül, hogy melyik programhoz tartozik az esemény, utána a program saját eseménylistájába kerülnek az események.
A folyamat feldolgozza az eseményt megfelelően reagál rá, majd a reakció alapján visszaküldi a GUI-nak a képernyő módosítására vonatkozó igényét.
A GUI, mint szolgáltató elvégzi a számára kirótt feladatot.
Az egyes programok ablakai egymást átfedhetik, a grafikus rendszer gondoskodik arról, hogy a teljesen vagy részben lefedett ablak tartalma a háttérben eltárolódjon és amikor az ablakról levesszük takarást, a tartalma megjelenik. Az újra megjelenítés során a GUI küld egy speciális üzenetet az alkalmazásnak, amelyben kéri, hogy a takarásból kikerült rész tartalmát újra küldje el.
Az egyes alkalmazások ablakainak lehetnek gyermekei, azaz olyan ablakok, amelyeket a fő alkalmazás ablak hoz létre. Ezek az ablakok néha csak a szülő ablakon belül mozoghatnak, máskor tetszőlegesen helyezkedhetnek el a képernyőn.
Ha egy folyamat több ablakot megjelenít, akkor az egyes ablakok lehetnek modal és non-modal ablakok.
A modal ablak azt jelenti, hogy a program ekkor ezen az ablakon keresztül vár adatbevitelre, a program más ablakát nem lehet semmiféle módon elérni.
A non-modal azt jelenti, hogy a program megnyitott ablakát elhagyva nyugodtan lehet a program más megnyitott ablakait használni.
Egér használata esetén az eseményeket az egér és az ablakok koordinátáiból azonosítja a rendszer.
Az ablakok között van egy aktuális ablak, amelynek az állapota kitüntetett. Ennek az ablaknak a területén van elhelyezve az aktuális billentyűkurzor. Más néven ezt úgy mondjuk, hogy ezen az ablakon van az input fókusz. A kurzort a programozók által definiált sorrendben lehet mozgatni az egyes beviteli helyek között és az aktuális ablakot a rendszer által biztosított billentyűkombinációkkal lehet változtatni.
A grafikus felületeket úgy tervezik meg, hogy az alkalmazott különböző grafikus rendszereken és hardvereken ugyanazok a funkciók ugyanazokat az eredményeket adják. Ennek megfelelően a rendszerek a hardvertől a saját beállításainak paraméterei az induláskor átadják, amely adatokat az alkalmazói folyamatok szabványos függvények segítségével lekérdezhetnek, és ennek ismeretében jeleníthetik meg a kimenetüket. A GUI maga is figyelembe veszi ezeket a paramétereket. Ilyen adatok lehetnek a színek száma, a vízszintes és függőleges felbontás, stb.
Hogy a grafikus megjelenítés minél gyorsabb legyen, az egyes grafikus rendszerekben magas szintű, sok tulajdonsággal felruházott objektumokat definiáltak, amelyeknek az előállítását nem az alkalmazói programnak kell végeznie, hanem elvégzi helyette a grafikus alrendszer. Ennek érdekében az alkalmazói programnak csak meg kell mondania, hogy milyen objektumot akar megjeleníteni (object típusa) és meg kell adnia a hozzá szükséges paramétereket, illetve a paraméterek hiánya esetén, egyes esetekben a rendszer default értékeket ad meg nekik. Ilyen objektum az ablak, menü, gördítősáv, beviteli sor, nyomógomb, stb.
Ennek hatására a kliens és a szerver közötti adatforgalom minimálisra csökken.
Ha a rendszerben nincsen meg a megfelelő típusú objektum, vagy az alkalmazás saját maga akar előállítani ilyeneket, akkor gyakran bitmap-eket kell megjeleníteni. Ezeknek a megjelenítését egyes esetekben az alkalmazói programnak kell elvégezni, de egyes standard bitmap típusokat a GUI is meg tud jeleníteni. A megjelenítés sebessége azonban ilyenkor viszonylag lassú.
Az operációs rendszerek fejlesztői időről időre szembekerülnek a felhasználók meg-megújuló igényével arra, hogy a rendszerüket gyorsabban, hatékonyabban, biztonságosabban és kényelmesebben tudják használni. Mivel az operációs rendsze 959b15j rek fejlesztőinek kapacitása szűk, ezért a különböző célokra gyakran külső fejlesztők hozzák létre a megfelelő alkalmazásokat. Ezeket hívjuk segédprogramoknak.
Visszatekintve az operációs rendszerek fejlődésére a segédprogramok később általában valamilyen formában beépülnek az operációs rendsze 959b15j rbe.
Egyes esetekben a felhasználói igényeket nem az operációs rendsze 959b15j r bővítésével és nem abba beleépítve elégítik ki, hanem egy shell-t húznak rá a rendszerre, akár karakteres, akár grafikus rendszerről beszélünk. Ez a fajta megoldás azzal a hátránnyal jár, hogy a felhasználó és a hardver közé beékelődik még egy szint, amely a működést egyes esetekben lassítja.
Sokszor a segédprogramok csak egy bizonyos célra készülnek, majd a fejlesztők nem állnak meg és komoly tudású, iránymutató programrendszereket készítenek belőlük.
A segédprogramokat a leggyakrabban az alábbi kategóriákban szoktak készíteni:
Állománykezelés. A fájlok másolása, átnevezése, törlése, könyvtárak létrehozása, törlése, mozgatása, néha lemezek partícionálása, formázása. E programfajta tipikus példája a DOS-os rendszereken elkészült
Norton Commander. Ez a program olyannyira találkozott a számítógép használók igényeivel, hogy a kilencvenes évekre gyakorlatilag minden második PC-n futott, sőt gyakran az indult el. Egyes felhasználók azt hitték, hogy az is a DOS része. Rengeteg klónja készült: DOS Navigator, Volkov Commander, Windows 9x, és NT alatt a Windows Commander, FAR Manager, LINUX alatt a Midnight Commander.
Programfejlesztés támogatása. Az operációs rendszerek gyakran tartalmaznak Egy viszonylag egyszerű Text Editort, amivel forráskódot lehet előállítani, továbbá egy Linkert is, amellyel a programokat össze lehet szerkeszteni. A LINU szerves része még egy C fordító is.
Adatbázis kezelés. A legtöbb operációs rendszer adatbázisokat használ futás közben. Az adatbázisok kezelése gyakran nehézkes feladat, ezért előszeretettel fejlesztenek ki kisebb, egyszerűen kezelhető adatbázis kezelő rendszereket. Ilyen programok voltak kezdetben a Lotus, a Dbase, vagy manapság egy MySQL+kliens program, a Microsoft Access.
Számítógép diagnosztika. A PC-k robbanásszerű elterjedése miatt a felhasználók egy része lesz annyira szakember, hogy az egyszerűbb hibákat el tudja önmaga is hárítani. Ezekre a célokra fejlesztenek ki diagnosztikai és javító eszközöket, amelyek a gép és az operációs rendsze 959b15j r esetleges hibáit felderítik és azt lehetőség szerint ki is javítják. Ilyen program a PC-s világban a Norton Utilities, Nuts and Bolts, vagy régebben volt a PC Tools.
Kommunikáció. A hálózatok megjelenésével a hálózatok kezelése, az üzenetek küldése súlyponti kérdés lett. Ennek megfelelően a helyi hálózatok kezelésének technikája finomodott, megjelentek az egyszerűbb helyi levelező, üzenő programok, illetve az Interneten használható nagyobb lélegzetű programok is.
Természetesen a fő területek felsorolását folytathatjuk, hiszen a multimédia területén semmit nem említettünk és vannak egyéb olyan témák is, amelyekről itt helyhiány miatt nem beszélünk.
A grafikus rendszerek bevezetésének talán az egyik legfőbb indoka a felhasználók kiszolgálása volt. Ennek köszönhetően a grafikus rendszerek illethetők leginkább a felhasználóbarát jelzővel, ugyanakkor legyen világos az is, hogy nem csak grafikus rendszer lehet ilyen tulajdonságú!
Az alábbiakban felsoroljuk azokat a jellemzőket, amelyek felhasználóbaráttá tesznek egy programot.
Könnyű legyen megtanulni. A menürendszere legyen logikus, áttekinthető, a Gyorsbillentyűk legyenek kézreállók és a szokásokhoz igazodók.
Méretezhetőség. A kezdő felasználó kapjon sok segítséget, de a gyakorlott felhasználónak ne tolakodjanak be kéretlenül a varázslók, helpek stb... A különböző szintű felhasználók tudják saját ígényeikhez alakítani.
Visszavonható parancsok. Minden parancsot a véglegesítés előtt lehessen visszavonni (Cancel gomb) és lehessen visszapörgetni utasításokat (Undo)
Több szintű Súgó rendszer. Legyen tutorial a kezdőknek, technikai leírás a szakembereknek és általában helyzetérzékeny help a felhasználóknak. Lehessen keresni, egyszerűen előhívható legyen. (F1 gyorsbillentyű, Help menüpont.)
Használata nyelvközeli legyen. Az tasítások igékkel jellemezhetők, a paraméterek főnevek. A helyi nyelvekre adaptált változatok kövessék a helyi nyelv logikáját!
Minden utasításra adjon választ! Ha egy programban hosszab futási idők vannak, akkor egy felirat azt jelezze vagy egy számláló vagy folyamatjelző csík mozogjon a képernyőn.
A hasonló funkciókat hasonlóképpen lehessen végrehajtani.
A korábbi évfolyamokon definiáltuk a fájlokat, azonban látni kell, hogy az a fájl fogalom - összetartozó adatok halmaza - nem elég kézzelfogható, de később meglátjuk, hogy ennél körülhatároltabb nem lehet.
Először is miért szükségesek a fájlok és hogyan alakult ki a fájl fogalma?
A mágnesszalagok korában csak szekvenciálisan lehetett írni a szalagokat, és az összetartozó adatok egymás után helyezkedtek el a szalagon. Minden egységnek egyedi azonosítót kellett adni, ami először csak egy sorszám volt. Az olvasó egység elölről végigolvashatta a szalagot, és megszámolhatta, hogy hányadik felvétel. A gyorsabb működés érdekében a szalagos egységek egy bevezetőrészt tettek minden felvétel elé, amely szinkronizálta az olvasást, ugyanakkor fejléc információt is írtak bele.
A mágneslemezek megjelenésével a rendszerek először még az adatok fizikai elhelyezését kezelték, de később már névvel hivatkoztak az adatokra. Ez lett a fájlnév.
A fájlneveknek mindig egyedinek kell lennie. A mágneslemezek megjelenésével már nem lehetett a fájlokra fizikai elhelyezkedésükkel hivatkozni, ekkor létrehozták a lemezeken a katalógusokat.
Mikor a mágneslemezek kapacitása már olyan méretűvé vált, hogy nem lehetett egy katalógusban kezelni az állományokat, létrehoztak olyan katalógusrendszert, amilyen a mindannyiunk által ismert alkönyvtárak rendszere.
Egy szintű katalógusrendszerről beszélünk, ha egy adathordozón csak egy lista van. (C-64 floppyja)
Két szintű katalógusról beszélünk, ha van egy alkönyvtárszint.
Több szintű katalógusról beszélünk, ha a könyvtárak elvileg tetszőleges mértékben egymásba ágyazhatók (gyakorlatilag sohasem!)
A fájlok és a katalógusok együttesen fájlrendszert alkotnak.
Azt gondolhatnánk, hogy készen vagyunk a defincióval, de egyes operációs rendszerek, mint például a unix és a Linux rendszerek az alapvető be- és kimeneti perifériákat és általában minden adatfolyamot fájlként kezelnek, ezért a fogalmat még általánosítjuk.
Ennek megfelelően a fájlok olyan adathalmazt jelentenek, amelyeket egy névvel azonosíthatunk.
Ez már jó definíció, hiszen programozáskor a fejlesztőnek nem kell tudnia, hogy egy fájl fitikailag létező, lemezes fájl, vagy csak egy bemenet vagy egy kimenet. A fájlnév átírásával módosítani lehet könnyen a program működését.
Ha a fájlrendszerben lévő fájlokról beszélünk, akkor a fájlokat létrehozásuk és felhasználásuk céljai szerint osztályozhatjuk:
Ideiglenes állományok. Ilyen az összes Virtális memóriát tartalmazó fájl, telepítéskor vagy működés közben létrejött ideiglenes (temporary) fájl. Az operációs rendszerek külön algoritmust használnak olyan fájlnevek létrehozására, amelyek különböznek egy adott könyvtárban található más nevektől, ráadásul véletlenszerűek!
Felhasználói állományok. A felhasználó azért hozza létre tudatosan az állományokat, hogy adatokat tároljon bennük, de a futtatható programokat is ide soroljuk.
Adminisztratív állományok. Az operációs rendszer folyamatai által létrejött és azok által kezelt fájlok. A felhasználók általában nem tudnak közvetlenül hozzájuk férni.
A fájlokat tartalmilag rengeteg osztályba lehetne sorolni, de nem lenne igazán egyik sem helyes általában. Az egyes operációs rendszerek a fájlokat funkcióik szerint megkülönböztetik például a nevükkel, míg mások nem. Ez utóbbi esetben a fájlrendszerben helyeznek el egy tulajdonságot (attributum), ami jelzi, hogy a fájl futtatható, vagy a fájl tartalma aapján dönti el az operációs rendsze 959b15j r a futtathatóságot, vagy a felhasználás módját.
A felhasználói programok közvetlenül nem érintkezhetnek a hardverrel, ezért az operációs rendsze 959b15j r szolgáltatásait kell igénybevenniük, ha fájlt akarnak létrehozmi, írni olvasni, törölni. A fájlok kezelését az operációs rendsze 959b15j r kernelének fájlkezelő része hajtja végre. Ennek a folyamatcsoportnak adja át a kéréseit a felhasználói program, vagy ettől kap vissza a fájlra vonatkozó adminisztrációs adatokat (handler száma, stb...)
Az adatok írása és olvasása azonban általában pufferelt módon egy cache-en keresztül megy, amely az operációs rendsze 959b15j rtől függően többé kevésbé beleavatkozik a fájlok fizikai írásának időpontjába. Előfordul olyan eset a NetWare-en, hogy a szerverre írás és a fizikai írás között 3-5 másodperc is eltelik!
A fájlok tartalmának olvasása is általában bufferelt módon megy, mivel egy fájl olvasásának megkezdésekor valószínűleg a fájl tartalmát a programtovább olvassa, ezért a rendszer ha teheti, az egész fil tartalmát beolvassa pufferbe és innen szolgáltatja a felhasználói programonak.
A fájlkezelő a megfelelő device driverek közbeiktatásával végzi el feladatát, így valósítva meg azt, hogy a hálózati kapcsolatokban lévő fájlok sem különbözzenek a helyi klemezeken lévőktől, vagy a CD-ROM-okon lévő fájlok ugyanolyan értékűek legyenek, mint az írásvédett floppykon lévők!
A felhasználói folyamatok a fájlokra nevükkel hivatkoznak. A különböző operációs rendszerekben a fájlnevek adásának a szabályai eltérőek, de a nevek általában két részből állnak:
A név első fele egyedi, a fájl tartalmára utaló rész, a második része pedig a fájl jellegét jelzi. A fájlnevek ben használhatók az ASCII kódrendszer karakterei, nagy és kisbetűk, numerikus jelek és speciális karakterek, mint például a '!@#&$^_-§, kivéve azok, amelyek az adott operációs rendszerben jelentéssel bírnak, mint példál a következő jelek: / \ | <> : ;. , ? *
Elvileg használhatók az ékezetes karakterek is, de a DOS, Windows, Win8x, Windows NT különböző nyelvi verziói másként kódolják a karakterket, ezért nem biztos, hogy azt a fájlnevet, amelyet az egyik rendszerben pl. Win98 magyar, kezelni tudunk másikban, példáulWin98 angol! Tipikusan az é, É, á, Á ő, Ő, ű,Ű, ó, Ó jelek nem kezelhetők. Az ilyen fájlokat a rendszer nem tudja törölni, megnyitni, átnevezni, stb.
Az alábbi rendszerekben a következő szabályok vannak:
MS-DOS
A nevek két részből állnak, a kettő között pont található. Az első rész maximum nyolc karakter lehet, a második rész maximum 3. Az MSDOS a fájlneveket automatikusan nagybetűre konvertálja.
Windows 9x, Windows ME, Windows NT, Windows 2000
Kettős elnevezésrendszert használ, a fájloknak van egy rövid és egy hosszú neve. A hosszú név maximum 250 karakterből állhatnak és a fentiek szerinti karakterek használhatók benne. Nem konvertálja a nevet a rendszer, de a kis és a nagybetűk azonosnak számítanak, azaz a RETIheja_FIA.DOC és a retiheja_fia.doc ugyanazt a fájlt jelöli. A rövid nevet DOS kompatibilitási okokból használja és a hosszú névből képezik oly módon, hogy a hosszú névből eltávolítja a szóközöket, majd az első nyolc karakterből képzi a nevet, ha a hosszú fájlnév kisebb, mint kilenc karakter. Ha hosszabb a hosszú fájlnév, akkor az első hat karaktert használja, utána ~jelet és sorszámot. Így különbözteti meg az azonosan kezdődő fájlokat. A kiterjesztés ugyanaz lesz, mint a hosszú változatban. Nem túlságosan szerencsés módszer!
UNIX, LINUX
Ebben a rendszerben a fájlnevek maximum 255 karakter hosszúak lehetnek, és tetszőleges számú ponttal elválasztott rész lehet bennük. A kis és nagybetűk különböznek, ezért a fájl.doc, FÁJL.doc különböző fájloknak számítanak. Az ékezetek és a speciális karakterek használatára ugyanazok a szabályok érvényesek, mint a DOS-ban.
NetWare
A NetWare régebbi verziói az MSDOS szabályai szerint képzik a fájlneveket. A NetWare 3.xx-es verziójától lehet hosszú fájlnevük. A hosszú fájlnevek használatakor fokozottan ügyelni kell az ékezetes karakterek használatára, a korábban jelzettek miatt, továbbá a DOS-os felületen használható felügyeleti programok nem mindig tudják azonosítani a fájlokat.
Helyettesítő karakterek.
Bár az alkalmazások általában pontosan használják a fájlneveket, de alkalmanként szükség van és alkalmaz a rendszer úgynevezett helyettesítő vagy más néven dzsóker karaktereket. Ezek helyettesítik a karakterlánc egy-egy karakterét vagy annak egy szakaszát.
A ? egy karaktert helyettesít, a * karakter után tetszőleges karakter állhat. A UNIX-ban a [ ] jelek közé írt karakterek között bármelyik szerepelhet az adott helyen.
A fájloknak a fájlneveken kívül vannak egyéb jellemzői is. Ezek operációs rendszerenként különböznek, de amelyben közösek az itt most felsoroljuk:
A fájl utolsó módosításának időpontja.
A fájl mérete, általában byte-okban
Archiválandó - módosult archiválás óta
Csak olvasható (read only) - Az egyszerű alkalmazások nem tudják módosítani, törölni
Rendszerfájl (system) - Az operációs rendszer speciálisan fontos fájljai
Rejtett fájl (hidden) - az egyszerű alkalmazások nem látják
A katalógusokat a katalógus jelzőbit jelzi. (directory)
UNIX, LINUX
Szimbolikus hivatkozás (link)
Ideiglenes adatcsere fájl (pipe)
Fájl tulajdonosa - az operációs rendszerben kerül lementésre
UNIX, LINUX, Windows NT NTFS fájlrendszere, NetWare esetén a fájlhoz tartalmaznak azok az adatok is, hogy ki olvashatja, módosíthatja, stb... azt.
A NetWare és a Windows 2000 esetén külön adatbázisban találhatók ezek az adatok!
A katalógusok bevezetését a mágneslemezeken tárolt fájlok mennyisége tette szükségessé. A mágnesszalagokon nyilván nem volt rá szükség, bár manapság a streamerek és a DAT archiváló eszközök korábban már használnak katalógust.
A mágneslemezeknél először egyszintű katalógust használtak, majd kétszintű katalógust később az általában elterjedt hierarchikus könyvtárstruktúrákat.
Az alkalmazások mindig az aktuális könyvtárban kezdik keresni a szükséges fájlokat.
Ha nem az aktuális könyvtárban keressük a fájlt, akkor elérési útvonalat kell megadni hozzá.
A fájlra való abszolút hivatkozásnak hívjuk azt, amikor a gyökérkönyvtárból indulva, a közbeeső könyvtárak felsorolásával hivatkozunk a fájlra.
Relatív hivatkozásról beszélünk, ha az aktuális könyvtártól számítva hivatkozunk a fájlra. A szülőkönyvtárt mindig a "..", aza két pont jelzi, míg az aktuális könyvtárat az "." egy pont.
A modern operációs rendszerekben minden fájlt nem kezelhet minden felhasználó. A szabályozásnak a követező elemei vannak:
A felhasználók valamilyen fájl és könyvtárelérési jogosultsággal rendelkeznek, illetve nem rendelkeznek
A fájlok és könyvtárak, amelyek használatát szabályozni akarjuk. Rendelkezhetnek speciális attribútumokkal.
Jogosultságok, amelyek megszabják a használhatóságot.
A jogosultságok általános típusai:
Olvasás (Read - R) - Olvasásra tudunk megnyitni egy fájlt.
Írás (Write - W) - Írásra tudunk megnyitni a fájlt
Létrehozás (Create - C) - Egyszer létrehozhatunk egy fájlt, írhatunk bele, de bezárása után már nem módosíthatjuk.
Végrehajtás (Execute - X) - A program betölthető, futtatható
Törlés (Erase - E) - A fájl törlésének joga. A fájlok törlése általában egy állapotváltoztatás, de nem jelenti az adatok fizikai megsemmisülését!
Módosítás (M - Modify) - A fájl tulajdonságainak módosítása
Hozzáférés módosítása (Acces Control - A) - Másoknak jogokat adhatunk arra a fájlra vagy könyvtárra, amelyhez ilyen joggal rendelkezünk.
A fenti jogosultságok a NetWare jogrendszeréhez hasonlítanak leginkább.
Itt megemlítjük, hogy a NetWareben egy user jogait egy helyen állíthatjuk be a különböző könyvtárakra, fájlokra, míg a Windows NT, 2000 esetén a könyvtárnál adhatjuk meg, hogy kinek van joga rá. A különbség abban keresendő, hogy a NetWareben külön adatbázisban tárolják a jogokat, míg az NTFS fájlrendszerben a fájlrendszer maga a jogok tárolásának helye.
Még nem beszéltünk arról, hogy fizikailag hol helyezkednek el a fájlok a lemezeken. A lemezeken lévő fájlok elhelyezése, fontos több szempontból is. A szempontok:
A lemezen lévő szabad területek jó kihasználása
Az adatok későbbi elérésének sebessége
A lemezeken blokkonként lehet elhelyezni az adatokat. A legkisebb megcímezhető blokkot clusternek hívjuk.
Az egyes blokkok foglalt vagy szabad állapotát a foglaltsági tábla mutatja meg. Ennek a táblának annyi eleme van, ahány cluster található az adott partícióban. A betöltött blokknak megfelelően a táblázatban a megfelelő helyen egyes vagy nulla van.
A táblázaton kívül a szabad helyek méretét és a a fájlok kezdőcímét tartalmazó láncolt listát tartalmazó katalógust is készíteni kell, amit a bittérképpel együtt karbantartjuk.
A fenti adatokat használva nézzük, hogy milyen stratégiák szerint tárolják le a fájlokat.
A későbbi felhasználás szempontjából a legjobb, ha a fájlok adatblokkjai folytonosan helyezkednek el a lemezen.
Az operációs rendszer megkeresi, hogy a fájl számára hol található elég hely a befogadására. Ha több ilyen hely is van, akkor azok közül ki kell választani egyet, az alábbi stratégiák szerint:
A fenti módszerek mindegyike esetén előbb-utóbb a lemezen lévő szabad helyek töredezetté válnak. Bár összességében van elég hely a fájlok elhelyezésére, de mégsem találunk elég nagy összefüggő területet. Ha túl precízen illeszkednek a fájlok, akkor a fájl méretének növelése nem lehetséges. Ha fájlból kitörlünk egy blokkot, akkor a fájl hátralévő részét előre kell mozgatni., ami lassú folyamat.
A fájlok helyének nyilvántartása egyszerű, hiszen csak a fájl kezdőcímét kell tudni, a többit ismerjük a fájl méretéből.
Ennél a módszernél a katalógusban csak a fájl kezdőcímét tároljuk, az összes többi adatot a fájl elhelyezési tábla vagy más néven FAT (=Fájl Allocation Table) tartalmazza. A FAT ugyanannyi adatot tartalmaz, ahány foglalási egység van a lemezen. Minden adat a fájl következő adatblokkjának címét tartalmazza, az utolsó blokk pedig 0-t tartalmaz.
Az eljárás előnyös, mert ha van elég hely a lemezen a fájl adatait el tudjuk helyezni. Nem korlátozza semmi sem a fájl méretét.
Hátrányos, hogy egy fájl n.-ik adatblokkjának eléréséhez végig kell menni a aláncolt listán, hogy megtaláljuk a helyét a lemezen.
A FAT viszonylag nagy tábla (FAT32 esetén clusterenként 4 byte ), amit memóriában célszerű tartani, mivel sokat használja a rendszer. A FAT sérülése esetén nincs mód a fájlok visszaállítására. A DOS, Win9x, Windows NT, NetWare éppen ezért két példányt tart fent a partíción.
A nagy táblázat helyett kisebbeket használva rugalmasabb rendszerhez jutunk. Egy nagy táblázatban a fájlhoz tartozó kisebb táblázat kezdőcímét tartjuk, a kis táblában pedig a fájlhoz tartozó blokkok címét, akkor az elhelyezési információt gyorsan elérhetjük, a módszer kevésbé sérülékeny, de hátrány, hogy meg kell becsülni a fájl méretét, mert akkorára kell választani a táblákat, hogy a fájlok értékei elférjenek. Nyilván nem lehet pontosan megválasztani a tábla méretét. A Unix és a Linux olyan módszert választott, amely megoldja a problémát.
A fájl táblázata 15 bejegyzést tartalmazhat, azaz a fájl első 12 blokkjának értékeit. Ha a fájl folytatódik, akkor a tábla 13. eleme a következő tábla kezdetére mutat, ahol tovább folytatódnak a fájl bejegyzései. Ha a fájl még ennél is nagyobb, akkor a 14. elem egy újabb indextáblát címez meg, ahol a nejegyzések további táblákra mutatnak (indirekt címzés). Ezt folytatva elég egyszerűen tárolhatjuk a fájlokat. A fájlból törölni itt az indexek mozgatásával lehetséges, ugyanakkor foglaltsági térképről külön kell gondoskodni.
Az állományok ( fájlok ) és katalógusok (könyvtárak) egy fájlrendszerben sok tekintetben hasonlítanak, másban különböznek.
Egy fájl létrehozásakor az operációs rendszernek gondoskodnia kell a megfelelő mennyiségű szabad blokkról, ahova elhelyezi a fájl adatait, le kell foglalnia azokat, majd elhelyezni bennük az adatokat.
Katalógusok nem különböznek a fájltól, számukra is le kell elfoglalni a megfelelő helyet, és beléjük kell írni az adatokat. A katalógusnál az egyetlen különbség az, hogy az operációs rendszer speciális attribútummal látja el a katalógust, ami megkülönbözteti azt a többi fájltól.
A katalógus tartalmát célszerű rendezetten tartani, hogy a keresések gyorsak lehessenek. Az MS-DOS és a Wni9x, NT nem rendezi a bejegyzéseket.
Bármilyen fájl művelet a fájl megnyitásával kezdődik. Az operációs rendszer ellenőrzi a jogosultságok meglétét, és ha minden ok., akkor létrehozza a fájl leíró táblázatát a Fájl Control Block-ot. Ebben tartja ezután a fájlhoz tartozó fontos és aktuális adatokat a rendszer.
A fájl megnyitása négy féle lehet:
Írás (Write)
Olvasás (Read)
Hozzáfűzés (Append)
Írás/olvasás
A fájl adatainak értelmezése lehet:
Bináris - Amikor a beolvasott értékek pontosan megfelelnek a lemezen tárolt értékeknek
Szöveg - amikor az olvasás a fájl vége karakternél leáll, egyes karaktereket pedig a rendszer konvertál.
A fájl elérése szerint lehet
szekvenciális - amikor az adatokat csak sorban lehet beolvasni
véletlenszerű (tetszőleges, random) - amikor az olvasás és az írás mutatóját programból állítjuk.
Az aktuális pozíció helyét az FCB tartalmazza.
A fájlban való pozicionálás (seek)
A fájl pointer állítását jelenti. Általában egy rekord írása vagy olvasása a mutató egy rekordnyi ugrását vonja maga után. A fájl elejére és végére speciális utasítások viszik a mutatót. A mutatót még adott rekordsorszámra is lehet pozícionálni.
A fájlból való olvasás és írás mindig a fájlpointer által mutatott helyről történik.
A fájl bezárása külön művelet. Hatására az pufferekben lévő adatok lemezre íródnak, az FCB-ben tárolt adatok megszűnnek, az FCB is megszűnik.
A fájl vagy katalógus törlése nem fizikai. Az állományt ellátja az operációs rendsze 959b15j r egy törölt jelzővel.
Az MS-DOS sorsára hagyja az ilyen állományokat. Ha felülírja más program az állomány területét, akkor nincs esély a visszaállításra. A Win9x, Win NT és Win2000 minden partíción egy recycled nevű könyvtárban helyezi el a bejegyzést, és ott őrzi előre meghatározott ideig illetve a könyvtár meghatározott méretéig. A NetWare addig őrzi a törölt fájlokat egy listában, amíg nem lesz szükség az általuk elfoglalt helyre. Ilyenkor a legkorábban törölt állományokat távolítja el véglegesen a partícióról. A LINUX ?.
Ezen felül az állományok tulajdonságanak módosítása lehetséges, de ez csak a katalógusban történő bejegyzéseket jelenti.
A legrégibb nagy mennyiségű adat tárolására alkalmas eszközök a mágnesszalagok. Nagy mennyiségű összefüggő adat tárolására használják őket. Streamer és DAT magnókat használnak erre a célra. A streamerek a hagyományos eszközök, személyi számítógépeken használatosak, míg a DAT magnók szerverek archiválására alkalmasak.
Tipikus felhasználási területeik:
Adatmentés, backup (napi, heti)
Ritkán használt szoftverek tárolására
Adatok átvitele számítógépek között. (Több gigabyte adat mozgatásának legolcsóbb módja)
Nagy mennyiségű adat átmeneti tárolása
A szalagokon egymás alatti sávokban 9 bites adatrögzítés történik. Nyolc bit adat, egy paritásbit. Egy 9 bites adag egy frame. A framek rekordokba szervezettek, a rekordok között kis szünetek vannak (inter rekord gap) a rekordok fájlokat alkotnak, a fájlok között szintén szünetek vannak.
A mágneslemezek kezelése a legösszetettebb feladat a különböző háttértárak kezelését összehasonlítva, ezért a továbbiakban ezt tárgyaljuk legrészletesebben.
A mágneslemezeken az adatokat egy tengelyen lévő, egyszerre forgó lemezeken lévő mágnesezhető rétegekben tárolják. A lemezeknek általában mind a két oldalán van mágneses réteg. Az adatokat oldalanként egy-egy író/olvasó fej olvassa. A fejek egyszerre mozognak sugárirányban, míg a lemezcsomag nagyon gyorsan forog. Tipikus forgási sebessége 5400, 7200, 10800 fordulat/perc. A lemezeken az adatokat körkörösen tárolják. Az egy lemezen lévő sávokat track-nek hívjuk. Az egymás alatt elhelyezkedő track-eket cylindereknek hívjuk. A lemezen tortaszerűen szektorokra bomlik. A track-ek és szektorok metszéspontjait blokkoknak hívjuk. Az egy blokkban lévő adat mennyisége jelenti a winchesterre átvihető legkisebb adatmennyiséget. A blokkok az adatokon kívül szinkronjeleket, blokk azonosító jeleket, ellenőrző összegeket is tartalmazhatnak. Ezt a logikai szerkezetet a gyártás során az un. Alacsonyszintű formázással alakítják ki. Az alacsonyszintű formázásra általában a PC-k nem alkalmasak, a HDD-ket nem is célszerű utólag ilyen folyamatnak kitenni, hiszen jobb hatásfokkal nem lehet ezt elvégezni, mint a gyárban. A blokkok mérete 0,5-64 KB lehet.
A fej mozgási idő (seek time) - amennyi idő alatt eléri a kívánt sávot a fej - 10 ms körüli.
Elfordulási idő (latency time) - 1/fordulatszám - kb 10 ms (7200 fordulatnál)
Adatátviteli sebesség (transfer time) - A blokk adatainak átviteléhez szükséges idő. Kb 2-10 MB/s
Egy mágneslemezes művelet esetén a HDD-nek az alábbi adatokra van szüksége:
Melyik blokkról van szó. Egy blokk megcímzéséhez szükséges adatok: lemezoldal (=fej, Head) sorszámát, a sáv (Cylinder) és a szektor (Sector) sorszámot.
Írás vagy olvasási művelet-e?
A számítógép operációs rendszere azonban nem ezt a címzést használja. Az operációs rendszerek a lemezeken lévő adatokat sorfolytonos blokkok sorozatának érzékeli, amelynek esetlegesen még a blokkmérete sem felel meg a fizikai blokkméretnek.
A felhasználói folyamatoknak a fentieken kívül még az alábbi adatokra van szüksége:
Az eszköz típusa (szalag, CD, floppy, HDD, stb.)feladatoknka
Az eszköz egyedi azonosítója, hogy az azonos típusok közül megkülönböztesse
Az adat kezdőcíme a megfelelő eszközön
Memóriacím, ahová majd elhelyezi az adatokat, vagy ahonnan kiolvassa azokat
Az adatok mennyisége
Írás vagy olvasás
A művelet befejezésekor értesítendő kernel folyamat azonosítója
Ennek megfelelően az operációs rendszerben futó folyamatok és a hardver között eszközmeghajtók (device driverek ) közvetítenek. Ezek az eszközök végzik el a szükséges konverziókat oda és vissza is.
Az eszközmeghajtók felépítése réteges. Nagyjából az alábbi blokkséma jellemzi:
Felhasználói folyamat |
|||||||
Kiszolgálandó feladat |
|
||||||
|
|
Megszakítás Vezérlés |
|||||
DMA vezérlő |
| ||||||
Az eszközkezelő felső szintje az operációs rendsze 959b15j r folyamataival tartja a kapcsolatot. Feladata, a kérések átvétele, vizsgálata és sorbaállítása. Ha más szempont nincsen, akkor ennek a szintek a feladata a várakozási idő optimalizálása. Az átlagos várakozási idő mellett a várakozási idő szórása is fontos szempont. Könnyen belátható, hogy az író-olvasó fej a középső sávokat tudja a leggyorsabban elérni, ezért célszerűen ott kell elhelyezni a leggyakrabban használt file-okat.
Több különböző stratégia létezik az elérés optimalizálására:
Sorrendi kiszolgálás (Firs Come First Served)
A folyamatokat érkezési sorrendben szolgáljuk ki.Semmi optimalizálás nincsen benne, így elképzelhető, hogy a kiszolgálás során nagy várakozási idők alakulnak ki. A legegyszerűbb algoritmus. A módszer javítása a pick-up eljárás, amely azon alapul, hogy a fej mzgása során a közbeeső helyeken felszedi az ott található kéréseket.
A legkisebb elérési idő (Shortest Seek Time First)
A legkisebb fejmozgással kielégíthető kéréseket teljesíti először. Átlagosan a legyorsabb elérési időket eredményezi, de a távolabbi helyekre vonatkozó kéréseket csak bizonytalan idő múlva elégíti ki. A folyamatok Time-.out-ra futhatnak. A kérések kielégítésének szórása nagyon nagy lehet.
Pásztázó (Scan, Look)
Ennek során a fej állandóan mozog a szélső pozíciókban lévő kérések között. A fej a mozgás során az útba eső kéréseket menet közben teljesíti. A módszer előnye a viszonylag egyenletes elérési idő, de rossz esetben a fej csak egy teljes oda-vissza út esetén elégíthet ki kéréseket. A középső sávokra vonatkozó kéréseket gyakrabban elégíti ki a rendszer.
Egyirányú pásztázás (Circular Scan)
Az előbbi módszert javítja ez a módszer. Csak a fej mozgásának egyik irányában teljesít kéréseket a fej. A legtávolabbi kérés kielégítése után a legelsőre ugrik vissza a fej, így az átlagos elérési idő nem nagyon nő, de az elérési idők szórása jelentősen csökken.
Természetesen az éppen alkalmazandó módszer függ a device fizikai tulajdonságaitól (HDD, CD, FDD, hálózati eszköz), és a használat jellegétől (Munkaállomás, szerver, hálózati eszköz).
Mint említettük, a mágneslemezes egységek fej (Head = H) sáv (Cyilinder =C) és szektor (Sector =S) és az operációs rendsze 959b15j r lineáris címzése közötti átmenetet oda-vissza meg kell oldani. Problémát jelent a különböző blokkméretek alkalmazása is (Cluster mérete). Tobvábbi problémát jelent az, hog a gyártók a fizikai sorrendhez képest a szektorok logikai sorrendjét másképpen állapítják meg, ugyanis egy szektor adatainak beolvasása után a feldolgozási idő alatt a HDD lemez továbbfordul, tehát a fizikailag következő szektor adatait nem tudja tovább lvasni a gép, csek a 2 vagy 3 szektorral későbbi adatokat. Ennek megfelelően a HDD-k alacsony szintű formázásakor a logikailag következő szektort fizikailag két vagy három szektorral később helyezik el.
Most a legegyszerűbb esetet nézzük meg, amikor a cluster méret megegyezik a fizikai blokkmérettel, és a szektorok logikai sorszámozása megegyezik a fizikai sorrendjükkel is.
B =Az operációs rendszer által jegyzett blokk sorszáma, b =aktuális blokk sorszám, H =fejek száma, h =aktuális fej száma, C = cylinderek száma, c = aktuális cylinder, S =szektorok száma, s = aktuális szektor.
Az operációs rendszer így kapja meg a szükséges blokk sorszámot:
B = h*C*S + c*S + s
A kiszámítás inverzése is szükség van. Az alábbi algoritmus kiszámítja a megfelelő paramétereket:
h = b div (C*S), x = b mod (C*S)
c = x div S,
s= x mod S
A device driver megszakításon keresztül átadja a lemezegységnek a megfelelő fizikai paramétereket, majd utasítja a feladat elvégzésére, egyúttal a DMA kezelő hardvert is utasítja a megfelelő működésre.
A HDD a DMA segítségével elhelyezi a megadott memóriaterületen a kért adatokat, amelyeket a HDD-ből közvetlenül megkap, majd a feladat befejezése után megszakításon keresztül értesíti a device driveren keresztül, a kernel megfelelő rutinját, amely értesíti a felhasználói folyamatot. A DMA csak fizikailag létező címre tud írni, így ha a folyamat a virtuális memóriában tartózkodik esetlegesen, akkor azt előbb be kell tölteni a fizikai memóriába.
Aszinkron átvitel esetén az étvitelt elindító folymatnak kell gondoskodnia a megfelelő fogadó memóriaterület rendelkezésreállásáról, amely a programozást kissé bonyolítja.
Szinkron átvitel esetén az operációs rendszer gondoskodik a fogadó memóriaterületről, és a fogadás befejzése után átmásolja az adatokat a folyamat területére.
Átmeneti tárak alkalmazása
A felhasználói folyamat átmeneti tárakat biztosíthat a saját területén az átvitel gyorsítására. Ennek célja, hogy a nagyobb tömegű beolvasott adatot egyszerre dolgozza fel. Előnye, hogy a folyamat futása kezdetén lefoglalhatja magának a megfelelő puffereket, így később nem kell erőforrásokra várnia futás közben. Célszerű külön írás és olvasási puffert kialakítani. Aszinkron folyamatoknál célszerű alkalmazni.
Lemezgyorsítás (Disk caching)
Az operációs rendszer területén alakítunk ki megfelelő méretű puffereket. Az operációs rendszermegfelelő folyamatai nem csak a felhasználói folyamat által megkívánt adatokat olvassa be, hanem továbbolvas a lokalitási elv értelmében (=leggyakrabban a következő adatblokkokra lesz szükség).
Íráskor az operációs rendszer pufferébe elegendő tölteni az adatokat, az írásról a rendszer gondoskodik majd. Az operációs rendszer az általa megszabott időben írja ki fizikailag a lemezre az adatokat (write back cache). Megjegyzendő, hogy egyes szélsőséges esetekben a folymat által kezdeményezett írás és a fizikai írás között több másodpercnyi idő is eltelhet, ami ezen a szinten óriási időt és veszélyforrást jelent. Amikor a fizikai irás azonnal lezajlik, ezt az esetet write through cache-nek hívjuk.
Blokkméret optimalizálás
Láttuk, hogy a HDD-k blokkmérete általában 0,5 - 64 kb között van, de inkább a kisebb érték az igaz. A file-ok tárolásához a winchesteren lévő blokkokat le kell foglalni és gyakorlatilag minimális az esélye annak, hogy egy file mérete N* blokkméret legyen, ezért az utolsó lefoglalt blokk egy része kihasználatlan marad. Sok file és nagy blokkméret esetén a kihasználtság hatásfoka erősen romlik, például FAT16 és 32 kb-os blokkméret és sok file esetén akár a terület 20-30%-a is veszendőbe mehet. A megoldás, akkor a kis blokkméret lehetne.
Sajnos nem lehet akármilyen kis blokkokat használni nagy winchester esetén, ugyanis minden operációs rendszernek szüksége van egy foglaltsági térképre, amely megmondja, hogy mely blokkok foglalta és melyek nem. A táblázatban blokkonként legalább egy bitet tartalmazni kell, amelynek értéke jelzi az illető blokk foglaltságát. Ezt a táblát az operációs rendsze 959b15j rnek a memóriában kell tartania, hiszen a tábla rendkívül gyakran változik. Minél kisebb a blokkméret, annál nagyobb lesz a tábla mérete, azaz a memória foglaltsága is. Az MS-DOS esetén a korábban tanultak szerint automatikusan változik a blokkméret a partíció méretével.
A Win9x esetén a hardver memóriája elvileg korlátlan, ezért a FAT 32-nél a blokkméret eléggé nagy partíciók esetén is csak 2 kb-osak.
A NetWare 4.xx alapesetben 32 kb-os blokkméretet alkalmaz, de a veszteségek elkerülése miatt a szuballokáció segítségével a töredék file-okat összevonja egy-egy közös blokkba, amelyet külön nyilvántart.
Az alábbiakban néhány tömörítési algoritmust ismertetünk. Az adattömörítés alapja a redundancia. Redundáns információról beszélünk, ha az információban ismétlődések vannak, vagy az információ bizonyos részei olyan adatokat tartalmaznak, amelyek az információ más részéből előállíthatók.
A tömörítési módszerek elve az, hogy a redundanciát megszüntessük vagy csökkentsük le minimális mértékben. Ha az információ redundanciáját megszüntettük, akkor azt tovább nem lehet tömöríteni semmilyen módszerrel..
Az alábbiakban nhány adattömörítési módszert ismertetünk
A most következő algoritmusok (a SPACE=>TAB, a "szemétgyűjtéses" és a tokenes eljárások) NEM "igazi" tömörítők, ugyanis számunkra a betömörített adat a cél, s nem az eredeti visszaállítása (amit nem is lehet mindig 100%-osan megtenni). Ennek ellenére a tömörítők közé soroltam ezeket is, mivel céljuk megegyezik a tömörítőkével, itt is helymegtakarítás a cél.
Ez az eljáráscsoport a legrégibbek közé tartozik, még az írógép korszakból öröklődött. Alapvetően kétfajta megvalósítása ismert, bár az általam elsőként leírt pozíció-eléréses konverzió a széleskörűen (szövegszerkesztőkben és editorokban is) használt. A pozíció-eléréses SPACE=>TAB konverziónál a sorban az előre meghatározott (minden negyedik, nyolcadik, vagy a letárolt) pozíció eléréséhez szükséges szóközöket helyettesíti az algoritmus egyetlen karakterrel, a TAB-bal (ASCII 9), míg a másiknál, a csoportos SPACE=>TAB konverziónál meghatározott mennyiségű (általában 4 vagy 8) szóköz helyett tárolja le a TAB karaktert. Tekintsük meg mindkét eljárás algoritmusát:
Pozíció-eléréses konverzió
Ciklus amíg nem fájlvége
Sorolvasás(Sor)
i:=1 [i az oszlopszámot jelöli]
Ciklus amíg i<=Hossz(Sor)
db:=0 [db a szóközök számát jelöli]
Ciklus amíg Sor[i]=' ' és nem TAB-pozíció(i) és i<=Hossz(Sor)
i:=i+1; db:=db+1
Ciklus vége
Ha Sor[i]=' ' akkor
Kiír(TAB)
különben
Ciklus j=1-től db-ig Kiír(' ')
Kiír(Sor[i])
i:=i+1
Ciklus vége
Kiír(Sorvége)
Ciklus vége
Kiír(Fájlvége)
Csoportos konverzió
Ciklus amíg nem fájlvége
Sorolvasás(Sor)
i:=1 [i az oszlopszámot jelöli]
Ciklus amíg i<=Hossz(Sor)
db:=0 [db a szóközök számát jelöli]
Ciklus amíg Sor[i]=' ' és db<>TAB-csoport és i<=Hossz(Sor)
i:=i+1; db:=db+1
Ciklus vége
Ha Sor[i]=' ' akkor
Kiír(TAB)
különben
Ciklus j=1-től db-ig Kiír(' ')
Kiír(Sor[i])
Elágazás vége
i:=i+1
Ciklus vége
Kiír(Sorvége)
Ciklus vége
Kiír(Fájlvége)
Ezzel az eljárással a tömörítendő adatból a számunkra felesleges részeket távolítjuk el. Maga az eljárás a tömörítendő adat típusától függ, minden adattípusra (már ha lehet rá alkalmazni az elvet, azaz van benne felesleges adat) más és más. Leggyakrabban szövegfájloknál alkalmazzák, ilyenkor felesleges adatnak minősülnek a sorok végén lévő szóközök, illetve a fájl végén lévő üres sorok, de létezik EXE fájlok relokációs tábláját tömörítő eljárás is. A szövegfájloknál alkalmazott eljárás algoritmusa (ez most csak a sorok végéről vágja le a felesleges szóközöket) a következő:
Ciklus amíg nem fájlvége
Sorolvasás(Sor)
i:=Hossz(Sor) [i az oszlopszámot jelöli]
Ciklus amíg (i>=1 és Sor[i]=' ') i:=i-1
Ciklus j:=1-től i-ig Kiír(Sor[j])
Kiír(Sorvége)
Ciklus vége
Kiír(Fájlvége)
Ez a tömörítés főleg interpreter nyelveknél (pl. a legtöbb BASIC ilyen) szokásos, ahol mind a program végrehajtási (értelmezési) idejének, mind méretének csökkentése miatt használják. Az algoritmus az utasításszavakat fordítja le kódokká, úgynevezett tokenekké, melyeket az interpreter gyorsabban képes feldolgozni, ugyanis nem kell értelmeznie, azaz minden egyes lépésnél lefordítania az utasításokat. A legegyszerűbb tokenes tömörítésre példa a következő algoritmus:
Ciklus amíg nem fájlvége
Szóolvasás(Szó)
i:=1 [i az utasítás sorszáma az utasítástáblázatban]
Ciklus amíg i<=UtasításokSzáma és Szó<>Utasítás(i)
i:=i+1
Ciklus vége
Ha i<=UtasításokSzáma akkor Szó:=Kód(i)
Kiír(Szó)
Ciklus vége
Amennyiben ismerjük, hogy az információnk lassan változik, akkor az információ értékének tárolása helyett célszerű a kezdőértéket és az érték változását tároni. Ebben az esetben esélyünk van arra, hogy a változás kisebb helyet foglal el, mint maga az érték, így a tárolt információ is kevesebb helyet foglal el, mint az eredeti.
Például legyenek egy adatsor értékei 16 biten tárolva, de tudjuk, hogy a változás a szomszédos értékek között nem lehet 1 nél nagyobb. A változást elegendő ekkor két byte-on tárolni, hiszen 0= nem változik, 1 nő, -1 csökken. Ebben az esetben 1024 adat 2048 byte-nyi helyet foglal el eredetileg, de tömörítve csak 1024 *2 bit = 256 byte. Az adatokat negyedére tömörítettük.
Az RLE egy mozaikszó, jelentése Run Length Encoding, magyarul Futási Hossz Kódolás. Az alapötlet egyszerű: ha valamilyen byte-ból sok van egymás mellett, akkor nem a sok byte-ot tároljuk le, hanem a byte-ot, és a darabszámot. A megvalósítása csak egy lényeges problémába ütközik, a kitömörítő algoritmusnak ugyanis tudnia kellene, hogy a következő byte kódolatlan, vagy egy ismétlődés kódja-e? Ezt a problémát többféleképpen lehet megoldani, ezek közül 4 algoritmust mutatok be:
RLE #1
Ez az eljárás a legegyszerűbb, és több képformátum is használja (Targa, Tiff, és a PCX, bár ez utóbbi egy kicsit módosítva). A tömörített állomány blokkokból áll, s mindegyik tartalmaz egy 1 byte-os fejlécet, melynek a felső (7.) bitje mondja meg, hogy a blokk egy ismétlődést tartalmaz, vagy tömörítetlen byte-okat. Ha a 7. bit alacsony, akkor az alsó bitek azt adják meg, hogy mennyi tömörítetlen byte jön (eggyel csökkentve, hogy a tömörítés mértékét növeljük - 0 tömörítetlen byte-nak ugyanis nincs értelme), illetve ha a 7. bit magas, akkor a következő byte ismétlődésének számát (kettővel csökkentve) tárolják az alsó bitek. A betömörítő algoritmus - nagyon leegyszerűsítve, csak a lényeget bemutatva - a következő:
Ciklus amíg nem fájlvége
ByteOlvas(Első)
Ha Első=KövetkezőByte akkor
ImétlődésSzámol(Hossz)
Kiír(128+Hossz-2)
Kiír(Első)
különben
KülönbözőtSzámol(Hossz)
Kiír(Hossz-1)
Kiír(KülönbözőByteok)
Elágazás vége
Ciklus vége
RLE#2
Ez az elv is nagyon egyszerű, itt a tömörített ismétlődés kezdetét egy kitüntetett byte (fejléc-byte) jelzi. A fejléc-byte meghatározása többféleképpen történhet, például a legegyszerűbb és leggyorsabb megoldás, ha lefixáljuk, hogy pl. a 0-s byte legyen ilyen (ez szövegfájloknál tökéletes, hiszen azokban általában nincs 0-s byte, azonban adatfájloknál korántsem az), a legjobb pedig (tömörítés szempontjából), ha előbb végigolvasva a fájlt meghatározzuk a legkevésbé előforduló byte-ot (akkor jó, ha ez a byte elő sem fordul a tömörítendő állományban), melynek azonban hátránya, hogy kétszer kell végigolvasni a fájlt, így megnövekszik a tömörítés ideje.
Ez az elv kétféleképpen valósítható meg, az egyik, mikor az egyes ismétlődések csak egybyteosak lehetnek, míg a másik, mikor a byte-csoportok ismétlődését is lekezeljük. Az előbbi algoritmust itt, az RLE#2 alatt, az utóbbit pedig az RLE#3 alatt tárgyalom.
A konkrét megvalósítás tehát a következő: Ha az algoritmus három byte-nyit meghaladó ismétlődést talál, akkor a fejléc-byte, az ismétlődés hossza-1 és az ismétlődő karakter kerül letárolásra. Speciális eset, mikor fejléc-byte következik - esetleg több is -, ekkor a fejléc-byte-ot, és a fejléc-byte-ok száma-1 -et kell letárolni (ha csak egy fejléc-byte következik, akkor 0-át). Ha az előző esetek közül az egyik sem áll fenn, akkor minden kódolás nélkül le kell tárolni a következő byte-ot. Az algoritmus - megint csak vázlatos - megvalósítása a következő:
Ciklus amíg nem fájlvége
ByteOlvas(Első)
Ha Első=KövetkezőByte akkor
ImétlődésSzámol(Hossz)
Kiír(Fejléc-byte)
Kiír(Hossz-1)
Ha Első<>Fejléc-byte vagy Hossz>3 akkor Kiír(Első)
különben
Kiír(Első)
Elágazás vége
Ciklus vége
RLE#3
Ennek az algoritmusnak az alapelve megegyezik az RLE#2-ével, azonban ennél byte-csoportok ismétlődése is engedélyezett. A konkrét megvalósítás a következő: Ha fejléc-byte következik, akkor - függetlenül ismétlődésének számától - le kell tárolni a fejléc-byte-ot, egy 0-át, és az ismétlődést. Ha olyan byte, vagy byte-csoport ismétlődés következik, ahol az (ismétlődés-1)*hossz (a hossz byte-csoportnál a byte-csoport hossza, byte-nál pedig 1) nagyobb mint 3, akkor le kell tárolni egy fejléc-byte-ot, az ismétlődés-1 -et, a hosszt és végül a byte-csoportot, illetve a byte-ot. Ha ezek egyike sem fordul elő, akkor kódolás nélkül kell letárolni a következő byte-ot. Az algoritmus vázlata a következő:
Ciklus amíg nem fájlvége
Ha Következő=Fejléc-byte akkor
ImétlődésSzámol(Hossz)
Kiír(Fejléc-byte, 0, Hossz)
különben
Ha Következő=ByteCsoportIsmélődés akkor
CsopIsmSzámol(CsoportHossz,Ismétlődés)
Ha (Ismétlődés-1)*CsoportHossz>3 akkor
Kiír(Fejléc-byte)
Kiír(Ismétlődés-1)
Kiír(CsoportHossz)
Kiír(Csoport)
különben
Kiír(Következő)
Elágazás vége
különben
Kiír(Következő)
Elágazás vége
Elágazás vége
Ciklus vége
RLE#4
Ez az algoritmus nagyon jól tömöríti az ismétlődéseket, akár byte-ismétlődések, akár csoportismétlődések, és nem kell az optimális tömörítéshez kétszer végigolvasni a tömörítendő fájlt, mint az előző kettőnél. Csak egy hátránya van: nem kombinálható más eljárásokkal.
Az algoritmus a következőképpen működik: Ha byte-ismétlődést talál, és az ismétlődés kisebb mint 67 byte, akkor két 0 bitet, 6 biten az ismétlődés hossza-2 -t, majd az ismétlődő byte-ot tárolja le. Ha az ismétlődés hossza nagyobb mint 66 byte (max. 16449), akkor egy 0-s bitet, egy 1-es bitet, 14 biten az ismétlődés hossza-66 -ot, végül pedig az ismétlődő byte-ot tárolja. Ha ismétlődő byte-csoportot talál, akkor egy 1-es, majd egy 0-s bitet, utána 6 biten a byte-csoport hosszát, majd 8 biten a csoport ismétlődése-2 -t, végül a csoportot tárolja le. Ha nem ismétlődő byte-okat talál, akkor ha azok hossza kisebb mint 34, akkor 1,1,0 biteket, 5 biten a hossz-1 -et, végül a byte-okat, ha több mint 33 van belőlük, akkor 1,1,1 biteket, 13 biten a hossz-33 -at, végül a byte-okat tárolja le. Az algoritmus vázlata a következő:
Ciklus amíg nem fájlvége
Ha Következő=ByteIsmélődés akkor
IsmSzámol(Byte, Ismétlődés)
Ha Ismétlődés<67 akkor
Kiír(Ismétlődés-2, Byte)
különben
Kiír(64+(Ismétlődés-66) div 256)
Kiír((Ismétlődés-66) mod 256): Kiír(Byte)
Elágazás vége
Elágazás vége
Ha Következő=CsoportIsmélődés akkor
CsopIsmSzámol(Csoport, Ismétlődés, CsoportHossz)
Kiír(128+CsoportHossz, Ismétlődés-2, Csoport)
Elágazás vége
Ha Következő=NemIsmélődés akkor
NemIsmSzámol(Csoport, CsoportHossz)
Ha CsoportHossz<34 akkor
Kiír(128+64+CsoportHossz, Csoport)
különben
Kiír(128+64+32+(Ismétlődés-33) div 256)
Kiír((Ismétlődés-33) mod 256,Csoport)
Elágazás vége
Elágazás vége
Ciklus vége
A tömörítőcsalád alkotóiról (Abraham Lempel és Jakob Ziv) kapta nevét, akik 1977-ben jelentették meg az alapalgoritmust (1977-et jelent a névben szereplő 77-es szám). Az LZ77 alapú tömörítők letárolják az n db utolsó byte-ot, és amikor egy olyan byte-csoportot találnak, mely szerepel ebben a pufferben, akkor a byte-csoport helyett annak a pufferben lévő helyét és hosszát tárolják le. Az algoritmust sokan módosították, javították a jobb tömörítés érdekében, ezek közül a legismertebb megvalósítás James Storer és Thomas Szymanski nevéhez fűződik, ezt a tömörítést fogom most bemutatni.
Az LZSS tömörítés
Az LZ betűpár a névben a Lempel-Ziv párosra, az SS betűpár pedig a Storer-Szymanski párosra vonatkozik. Ez az algoritmus a "visszanéző" puffer (az utóbb letömörített n db byte-ot tartalmazza) mellett még egy "előrenéző" puffert is alkalmaz, melybe a letömörítendő byte-ok kerülnek. Az algoritmus megkeresi a letömörítendő byte-ok és a "visszanéző" puffer leghosszabb egyezését, s ha annak hossza meghaladja a minimálisnak definiált, általában 3 byte-ot, akkor egy pozíció, hossz párt tárol le. Megoldandó probléma még, hogy ennyiből a kitömörítő még nem tudná megállapítani, hogy a következő kód egy egyszerű byte-e, vagy pedig egy pozíció, hossz páros. Ezt az RLE-nél alkalmazott, az előzőekben leírt, módszerekkel is megvalósíthatnánk, azonban a tapasztalat szerint egyszerűbb és jobb, ha minden kód elé egy plusz bitet írunk ki, mely azt jelzi, hogy a soron következő adat byte, vagy visszautaló kódpár. (A gyakorlatban ezeket a biteket 8-asával tárolják a könnyebb kezelhetőség érdekében, azonban ez a lényegen nem változtat.) Az algoritmus vázlata a következő:
Ciklus amíg "előrenéző" puffer nem üres
EgyezésKeres(pozíció, hossz) [a maximum egyezés keresése]
Ha hossz>minimum_hossz akkor
Kiír(pozícó,hossz)
különben
Kiír(KövByte)
Elágazás vége
Ciklus vége
Az algoritmus több ötlettel is javítható, gyorsítható, pl. javulhat a tömörítés aránya, ha a következő pozícióra is megvizsgáljuk az egyezést, gyorsul a tömörítés, ha keresés során ún. HASH táblát alkalmazunk, stb. Mivel az algoritmus könnyen megvalósítható és jól tömörít, így gyorsan elterjedt.
Az család alapját képező LZ78 algoritmust - mint az LZ77-et -, szintén a Lempel-Ziv páros publikálta (1978-ban). Az algoritmus alapja, hogy egy táblát épít fel folyamatosan, melybe mindig belehelyezi az aktuális byte-csoportokat. Ha egy olyan byte-csoportot talál, mely már szerepel a sztringtáblában, akkor a táblában elfoglalt helye kerül letárolásra. Az ezen alapuló algoritmusok csak a tábla kezelésében és tárolásában különböznek. A legismertebb változat az LZW algoritmus, melyről a következőkben fogok írni.
Az LZW az LZ78 finomított változata. Terry Welch publikálta 1984-ben, a W betű az ő nevére utal az elnevezésben. Az LZW algoritmus is széleskörűen elterjedt, legismertebb megvalósítása a főleg UNIX rendszereken elterjedt COMPRESS program. Az LZW alapja azonos az LZ78-al. A kiírásra kerülő kódok általában 12 bitesek, így a sztringtáblába 4096 bejegyzés fér. Az első 256 bejegyzésbe előzőleg az egyszerű ASCII karakterek, 256-tól 4095-ig pedig a tömörítés során a byte-csoportok kerülnek. Az algoritmus előnye, hogy ezt a táblát nem kell letárolni, ugyanis kitömörítés közben minden további nélkül felépíthető. Az LZW a tábla tárolásában hozott forradalmi újítást, ugyanis az LZW táblájába nem az egész byte-csoport kerül bele, hanem csak a byte-csoport első byte-ja, majd egy, már a táblában szereplő byte-csoport indexe (a byte-csoport ebből a láncolatból könnyen felépíthető). Az algoritmus a következő:
ByteOlvas(Sztring)
Ciklus amíg nem fájlvége
ByteOlvas(Karakter)
Ha (Sztring+Karakter) benne van a táblában akkor
Sztring:=Sztring+Karakter
különben
Kiír(Sztring)
TáblaHozzáad(Sztring+Karakter)
Sztring:=Karakter
Elágazás vége
Ciklus vége
Kiír(Sztring)
Az algoritmus megvalósításakor a sztringtábla méretének (bitek száma) kiválasztása jelenthet problémát és annak meghatározása, hogy mi történjen, ha megtelik a sztringtábla. A két variáció (melyek ötvözhetőek): vagy a bitek számát kell növelni ilyenkor, vagy törölni kell a táblát.
A statisztikai algoritmusok lényege az, hogy az egyes byte-ok előfordulása alapján rendelik hozzá a byte-okhoz a megfelelő kódokat, a sűrűbben előforduló jeleket rövidebb, a ritkábban előfordulókat pedig hosszabb bitsorozattal kódolják. Az egyes byte-ok előfordulási értékét alapvetően két módszer segítségével lehet meghatározni.
Az első módszer két menetben tömörít. Az első menet során meghatározza a byte-ok eloszlását, majd a másodikban a már meglévő statisztikát felhasználva lekódolja a tömörítendő adatsort. Ezt a módszert hívják statikusnak. Egyik hátránya, hogy a tömörítendő adatot kétszer kell végigolvasni. Ez a hátrány kiküszöbölhető úgy, hogy az algoritmus blokkokra bontja a tömörítendő adatot, majd az első menetben nem csak a statisztikát veszi fel, hanem a blokkot betölti a memóriába és előkészíti azt a második menetben végrehajtandó kódolásra. Másik hátrányos tulajdonsága még, hogy a tömörített adat mellé (és lehetőleg elé, hogy a dekódolónak legyen mi alapján kitömörítenie) le kell tárolni a statisztikát is. Az eljárás kifejezett előnye viszont a sebessége, amely elég jónak mondható.
A második módszer nem készít előre statisztikát, hanem azt tömörítés közben állítja fel, a tömörítés megkezdésekor átlagos eloszlásúnak feltételezve az adatokat. Minden byte letömörítése után (melyet mindig az aktuális statisztika alapján tömörít le) módosítja a statisztikát. Ezt a módszert hívják dinamikusnak. Az algoritmus nagy előnye, hogy nem kell letárolni az eloszlást, mivel azt a kitömörítés közben is hasonlóan elő lehet állítani. Ennek az algoritmusnak is több hátránya van. Az egyik, mely a tömörítési arányt is befolyásolja az, hogy az eljárás feltételezi az adatsor homogén eloszlását, azaz hogy az adatsor elejének tömörítése során felállított statisztika igaz az adatsor további részeire is. A másik hátrány a tömörítés sebessége, ugyanis a byte-okhoz rendelt bitsorozatot minden lekódolt byte után újra kell számolni, amely viszonylag időigényes feladat.
Mint láthattuk, mindkét módszernek vannak előnyei és hátrányai, de a tapasztalat azt mutatja, hogy - átlagban - a két eljárás tömörítési aránya közel azonos. Ennek ellenére a statikus algoritmusok jobban elterjedtek, mivel kódjuk egyszerűbbnek mondható, és valamivel gyorsabban is dolgoznak. A legismertebb statisztikai kódolás a Huffman kódolás, a legígéretesebb pedig az aritmetikai tömörítés. Részletesebben e kettő működését mutatom be a következőkben.
Az eljárás alkotójáról lett elnevezve, aki már 1952-ben publikálta az eljárást. A korai ismertetés ellenére alkalmazása sokáig (1988-ig) váratott magára. A ún. kódfás algoritmusok között ez adja az optimális megoldást, s magának a programkódnak a megvalósítása is meglehetősen egyszerű. A tömörítés a következőképpen zajlik: Miután rendelkezésünkre áll az egyes byte-ok gyakoriságának statisztikája, felépítünk egy bináris fát. E kódfa felépítése visszafelé, a végpontokból indul. A legritkábban előforduló kódokat "kötjük össze", és előfordulásukat összegezzük. Ezt addig folytatjuk, míg a végén már nem marad összeköthető kód, a kódfa készen áll. Ezután ha meg akarjuk kapni valamely byte-hoz tartozó bitsorozatot, a csúcsból elindulva végig kell követnünk a fát, s ha pl. balra lépünk rajta, akkor egyes bitet, ha a másik irányba, akkor nullás bitet kell kiírnunk.
A Huffman kód igen jó eredményt adó algoritmus, s bár más, az előzőekben leírt tömörítési eljárásokkal kiegészítve ugyan, de a legtöbb tömörítőprogram ezt alkalmazza. Az eljárást magát ebben az esetben mellőzöm, mivel kódja a többi algoritmuséhoz képest összetettebb, és sok helyet igényelne.
Aritmetikai kódolás
Ez az eljárás talán napjaink legígéretesebb tömörítési módja. Az alapötletet már 1948(!!!)-ban publikálta Shannon, az eljárás kitalálója, azonban megvalósításának komoly sebességbeli és elvi akadályai voltak (egészen napjainkig, a számítástechnika robbanásszerű fejlődéséig). A kódoláshoz itt is szükség van a gyakorisági statisztikára.
A tömörítés a következőképpen történik: A kódoláshoz az egyes valószínűségeket felosztjuk - alapértelmezésben - a nulla és az egy közti tartományba (Az implementációk általában nagyobb indulótartománnyal dolgoznak). Például, ha a tömörítendő byte-csoport ACBA, akkor az A karakterhez a [0-0.5] intervallumot rendeljük, mivel valószínűsége 0.5, a B karakterhez a [0.5-0.75] intervallumot (valószínűsége 0.25), végül a C karakterhez a [0.75-1] intervallumot (valószínűsége szintén 0.25). A kódoláshoz először vesszük a [0, 1] intervallumot, és rávonatkoztatom az első karakterhez tartozó tartományt, mely a példában [0, 0.5], az eredmény a [0, 0.5] intervallum lesz. Erre a következő karakterhez tartozó tartományt kell vonatkoztatni mely esetünkben [0.75, 1], a kapott intervallum [0.375, 0.5], s így tovább, mindig a következő karakter tartományát kell az előzőleg kapott intervallumra vonatkoztatni, míg az adatok végére nem érünk. A példához tartozó végeredmény a [0.4375, 0.453135] tartomány lesz. Ebből a tartományból kell kiválasztanunk, majd letárolnunk azt a számot, mely binárisan a legkevesebb számjegyből áll. (A dekódolás menete nagyon hasonló, az eltérés, hogy az újabb és újabb intervallum-felosztásban ez a bináris szám mindig más-más - mindig a következő - karaktert jelöli ki.) A tömörítő algoritmusa a következő:
Alsó:=0
Felső:=1
Ciklus amíg nem fájlvége
Beolvas(Byte)
Tartomány:=Felső-Alsó
Felső=Alsó+Tartomány*(a Byte intervallumának felső határa)
Alsó=Alsó+Tartomány*(a Byte intervallumának alsó határa)
Ciklus vége
Kiír(Statisztika, Alsó)
Az algoritmus legnagyobb előnye a rugalmassága, ami annyit jelent, hogy az általam előzőleg bemutatott eljárások közül bármelyikkel összepárosítható (főleg statikus megvalósítás esetén), mivel a kódolt adat és a statisztikai modell jól elkülöníthető egymástól. További előnye még, hogy rendkívül kevés memóriát igényel, ezzel is elősegítve az ötvözést más tömörítési eljárásokkal. Az algoritmusnak azonban komoly hátrányai is vannak. Ezek közül a legjelentősebb, hogy minden byte kódolásakor több osztásra és szorzásra van szükség, melyek jelentősen lelassítják a tömörítést. A másik probléma, mely akadályozta az algoritmus megvalósítását, hogy a személyi számítógépek nem képesek olyan sok (könnyen akár 100) tizedesjegyű számok ábrázolására, melyet az algoritmus megkövetelne. A sebességbeli problémát különféle a szorzást és osztást segítendő matematikai táblázatokkal, illetve az újabb és újabb - mindig gyorsabb - processzorok pedig sebességükkel tűrhetően kiküszöbölik, az elvi probléma pedig különféle trükkökkel (pl. a már állandósult bitek letárolása, stb.) megszüntethető, így végül nem okoz problémát az algoritmus megvalósítása.
Az előző fejezetben ismertettük a redundancia fogalmát. Megvizsgáljuk, hogy milyen összefüggés van a megbízható rendszerek és a redundancia között.
Murphy sokszor emlegetett elve, hogy ami elromolhat, az el is romlik. A számítógépeken tárolt adatok hibátlansága és megbízhatósága manapság élet-halál kérdés.
Az adatok hibátlanságának ellenőrzése az első lépés. Minden hibaellenőrzési és hibadetektálási módszer azon alapul, hogy az adatok rögzítésekor az adatokon kívül egy ellenőrző értéket vagy értékcsoportot helyezünk el, azaz redundanciát viszünk az adatokba. Az adatok beolvasásakor kiszámoljuk az ellenőrző értéket ugyanazzal az algoritmussal, amivel azt előzőleg generáltuk és az így kapott értéket összehasonlítjuk a beolvasott ellenőrző értékkel.
Paritásbit.
Ez a legegyszerűbb hibadetektálási módszer. A paritásbit értéke 1, ha az ellenőrzendő adatsorozatban páros számú 1-es szerepel, 0 ha páratlan számú. A paritásbit értéke ellenkezőjére fordul, ha egy bit értéke a beolvasáskor átváltozik. Ha két bit értéke változik meg, akkor sajnos a paritásbit nem véd. Általában páratlan számú bit értékének módosulását tudja jelezni.
A paritásbit és minden más ellenőrző összeg képzésének általános módja a következő:
Tegyük fel, hogy a tárolt adatokat T[N] tömbben tároljuk, ahol N a tömb mérete, továbbá S lesz a végösszeg:
S := T[1]
Ciklus i:=2 től N-ig
S = S XOR T[i] (Logikai kizáró vagy mávelet)
Ciklus vége
Ki: S
Ha két paritásbitet alkalmazunk, az már ké bit hibát tudunk detektálni. Ha nyolc bit információról biztosan meg akaruk tudni, hogy valóban hibátlanul tároltuk-e, akkor ugyanannyi ellenőrzőbitet kell használnunk, azaz kétszer annyi adatot kell letárolnunk, mint az eredeti adat.
Sajnos a hibát ugyan tudjuk detektálni, de javítani nem. Miért elegendő azonban néhány paritásbit?
Tegyük fel, hogy egy adathordozón annak a valószínűsége, hogy 1 bit hibás 1/1000. Ha a hibák egymástól független eseményként fordulnak elő, akkor két bit hibájának valószínűsége akkor 1/1000000, azaz egymilliomod, 3 bithiba egymilliárdod!
Hibajavítás
Ha a hibák egymástól függetlenül fordulnak elő, akkor bebizonyítható, hogy n db adatbit n+1 db bitből álló hibajavító kód segítségével van lehetőség a hiba kijavítására. A hibajavításhoz az un. Hamming távolságot használjuk, amelynek lényege, hogy azt az adatot tekintjük jónak, amely a rossz adattól a lehető legkevesebb bittel tér el. A Hamming távolság kszámításának módja az, hogy vegyük az eredeti adatot és a hibaellenőrző kódot, majd kizáró vagy alkalmazásával nézzük meg, hogy az eredményben hány bitet kapunk. A kapottérték azt mondja meg, hogy hány db egyes hiba van a vizsgált adatban.
A hibák azonban gyakran csoportosanjelennek meg. A Hamming-kód egy trükkel alkalmas az ilyen esetekre is. Tegyük fel, hogy 8 bites informciót küldünk át valahová. K-db byte-nyi elküldendő adatot egymás alá írjunk bitenként balról jobbra, majd a mátrix elemeit nem sorfolytonosan küldjük el, hanem oszloponként K-s csomagokban. A megérkezés helyén összeállítva a mátrixot visszakapjuk az eredeti értékeket. Ha az eredeti adatban csoportos sérülés keletkezik, akkor az egymés uténi bitekben jelentkezik, k db különálló hibaként, így a Hamming kóddal vissza lehet állítani az adatok eredeti értékét.
Ellenőrző összegek (Cyclic Redundancy Check = CRC)
Ha nagyobb mennyiségű adat hibája valószínűsíthető és a hibák csoportosan fordulhatnak elő, akkor célszerű komolyabb méretű ellenőrző összegeket képezni, a fent vázolt algoritmus segítségével. Ebben az esetben a hiba nem javítható ugyan, de a hiba megléte megállapítható.
Gyakorlati hibavédelem
A gyakorlatban a hibák ellen sok féle módon védekeznek, de minden esetben redundáns információt helyeznek el a meghajtón.
Ilyen módszer a lemeztükrözés (mirroring), amikor is minden adatok két különálló lemezre mentenek el. Az operációs rendszer mindig számolja az ellenőrző összegeket az írásoknál és olvasásoknál és amelyik meghajtón nem stimmel az összeg, az hibázott, és a másikról esetleg vissza lehet állítani az adattartalmat.
A RAID (Redundant Array of Inexpensive Disks) rendszerek azon alapulnak, hogy viszonylag olcsó HDD-ket összekötve az adatokat úgy mentik a lemezekre, hogy a hiba mindig kiderül és a rendszer működés közben is képes javítani az adatokat. Csak speciális operációs rendszerek képesek ezen rendszerek támogatására, illetve újabban megjelentek ilyen alaplapok is, ahol a BIOS épes bizonyos RAID funkciók végzésére.
A korábbiakban definiáltuk az erőforrások fogalmát, ezért itt nem tesszük meg. A preemptive és a megosztható erőforrások kezeléséről később lesz szó, az alábbiakban olyan erőforrások kezeléséről lesz szó, amelyek:
Nem megoszthatók (non-sharable)
Hasznélatuk nem megszakítható (non-preemptive)
Korlátozott számúak
Egész számúak
Egyenrangú elemekből álló osztályokra bonthatók. Egy osztályon belül lényegtelen, hogy egy folyamat melyik erőforrást kapja meg.
Az erőforrásokat az operációs rendszerben futó folyamatok igénylik, a kerneltől. A kernelnek az a része, amit erőforráskezelőnek hívunk valamilyen algoritmus szerint eldönti, hogy az adott típusú erőforrás igény kielégíthető-e, ha igen, akkor a a folyamat tulajdonjogát bejegyzi a folyamatleíró blokkba, és összekapcsolja a folyamatot az erőforrással. A folyamat a használat utá rendszerhívás által értesíti az erőforráskezelőt az erőforrás felszabadításáról, amit az erőforráskezelő meg is tesz.
Ha egy folyamat hibás működés folyamán lmegszűnik, akkor az erőforrásait esetleg nem képes felszabadítani, a rendszer nem biztos, hogy képes a felszabadítást detektálni. Ekkor néha a rendszer úgy gondolja, hogy rendbenlezajlott minden és végülis felszabadítja a folyamatot.
Ha egy folyamat ígényét nem lehet kielégíteni, akkor a folyamat egy ideig vár és időközönként újra megkísérli a foglalást.
Ha nem működőképes vagy nincs joga a folyamatnak a kért erőforrás használatához, akkor az erőforráskezelő végleges elutasítást küld a folyamatnak. Ekkor hibaüzenetet kap a folyamat.
Ha a kért erőforrás foglalt, akkor várakozásra felszólító üzenetet kap a folyamat, és egy várólistára kerül, amelyen az igény kielégítéséig marad.
Az erőforrások kezelésének ábrázolásásra az erőforrás-gráfot szokás használni:
A => Erőforrás jelenti az A folyamat erőforrás igényét.
A <= Erőforrás jelenti azt, hogy A az erőforrás tulajdonosa.
Ha egy folyamat ígényel egy erőforrást, és van szabad erőforrás akkor kielégítjük, ha nincsen, akkor nem. Egyszerű nem? Ezt hívják liberális megközelítésnek.
Sajnos egy probléma felmerül. Nézzük az alábbi példát:
A és B folyamatok mindegyikének futás közben két mágnesszalagos egységre van igénye. Az egyikről tölti a programréészeket, a másikról az adatokat. A szalagokat nem egyszerre kezdik, előbb a programot töltik be, majd később fordulnak az adatszalaghoz, de van olyan időszak, amikor mind a kettőt használják. Először mind a kettő a programot tölti be, majd az adatszalaghoz fordul. A rendszerben pontosan két db szalagos egység van, I és II. Az alábbi folyamat zajlik le:
A elindul és kér egy szalagos egységet A => I.
Az erőforráskezelő lefoglalja számára A <= I.
B elindul és kér egy szalagos egységet B => II.
Az erőforráskezelő lefoglalja számára B <= II.
A kéri a következő szalagos egységet A => II.
Az erőforráskezelő várakoztatja A-t, mivel nincsen szabad egység.
B kéri a következő szalagos egységet B => I.
Az erőforráskezelő várakoztatja B-t, mivel nincsen szabad egység.
Patthelyzet alakul ki. Ezt hívják holtpontnak (deadlock)!
A => I => B => II => A, vagyis a foglaltsági gráfban kör alakult ki!
Vacsorázó bölcsek problémája:
5 kínai bölcs ül egy kerek asztal körül, mindenki előtt ott a finom rizses kása és minden bölcstől jobbra és balra is van egy pálcika. Csak két pálcikával tudnak enni a bölcsek. Van-e olyan módszer, amellyel egyszerre mindenki jóllakik? Nincsen, de azért bölcsek, hogy a problémát megoldják. Valaki várni fog!
Négy autó a kereszteződésben
Holtpont alakul ki akkor is, amikor egy kereszteződésbe négy autó érkezik egyszerre, mindegyik egyenesen akar továbbmenni, és mindegyiknek elsőbbséget kell adnia a tőle jobbra lévőnek.
Holtpont akkor alaul ki, ha az erőforáskezelő gráfban találunk körutat
Ha megszüntetjük a párhuzamosságot a folyamatok között, akkor nem kerülhetnek versenyhelyzetbe, azaz egy időben csak egy folyamat rendelkezhet erőforrással. Amikor befelyezi működését vagy felszabadítja az összes erőforrását, akkor jöhetnek a várakozási sorban lévő többiek.
Sajnos ez a stratégia nem túlzottan optimális. Az erőforrások kihasználtsága nagyon csekély, a rendszer rettenetesen lassú lesz.
A mésik probléma az, hogyha a várakozási sor túl hosszúra nyúlik, akkor egyes folyamatok time-out-tal leállhatnak. Ha az erőforráskezelő a várakozási sorban álló folyamatok sorrendjét valamilyen prioritás alapján választja ki, akkor előfordulhat, hogy egyes folyamatok soha nem kapják meg a megfelelő erőforrásokat. Ezt az esetet KIÉHEZTETÉS-nek hívják.
Sajnos egyik véglet sem alkalmas az erőforrások kezelésére, ezért meg kell vizsgálni azt, hogy hogyan lehet kiküszöbölni a problémákat. Két lehetőségünk van, megelőzzük a holtpont kialakulását vagy a kialakult holtpontot a lehető legkevésbé fájdalmas módon felszámoljuk. Az előbbi módszer kevesebb veszteséggel jár. Nezzük meg, hogy mi kell ahhoz, hogy holtpont alakuljon ki.
A holtpont kialakulásának a feltételei
Vannak nem megosztható erőforrások, egyszerre csak egy folyamat használhatja őket, azaz kölcsönös kizárás van a rendszerben.
Az erőforrásokra várakozó folyamatok más erőforrásokat lefoglalva tarthatnak.
Vannak non-preemtive erőforrások
A folyamatok körkörösen egymásra várhatnak, ciklikus várakozás alakul ki.
A fenti feltételek közül legalább egynek a kialakulását meg kell akadályoznunk ahhoz, hogy a holtpont biztosan ne alakuljo ki. Az 1. éa 3. feltételegy rendszerben eleve adottság, azzal nem tudunk mit kezdeni, csak a maradék két feltételt vizsgálhatjuk.
A 2. feltétel kialakulását akadályozó módszer. A rendszerben elinduló folyamatnak indulás után egyszerre kell lefoglalnia a futása során szükséges összes erőforrást. Ha ez nem kielégíthető, akkor várnia kell a sorára. Ha megkap mindenszükséges erőforrást, akkor viszont nem fog más folyamatokra várni, hiszen minden szükséges megvan ahhoz, hogy befejezze futását.
Hátrány:
Folyamatok akkor is fogva tartanak erőforrásokat, amikor még vagy már nincsen szükségük rájuk, a rendszer csak egy kicsit hatékonyabb, mint konzervatív erőforráskezelés esetén.
A futás kezdetén nem mindig mérhető fel a szükséges erőforrásigény.
Fennéll a kiéheztetés veszélye!
Javítás
Ha egy folyamat leadja az összes erőforrását, akkor újra igényelhet erőforrásokat. Sajnos ez sem jelent túl nagy előrelépést, mivel az így felszabadított erőforrásokra a várakozó folyamatok rácsapnak, és a futó folyamat a várakozási sor végére kerül. Futása lelassul, gyakoribb lesz a kiéheztetés veszélye is.
A 4. feltétel kialakulását megelőző stratégia a következő.
Az erőforrások osztályaihoz a használat gyakorisága szerint növekvő sorszámokat rendelünk. Ha a folyamatnak egy osztályon belül több erőforrásra van igénye, akkor azokat csak egyszerre igényelheti.
A folyamat csak a rangsor szerint növekvő sorszám szerint igényelhet erőforrásokat, azaz ha már egy osztályból birtokol erőforrást, akkor a következő foglaláa csak magasabb osztályból történhet.
Ciklikus várakozás nem alakul ki, mert például, ha A folyamat lefoglalt a 5. osztályból már elég erőforrást, akkor csak a 6., 7., stb. Osztályból foglalhat le magának továbbiakat. Ha B vagy C folyamat szintén az 5. osztályból szeretne foglalni, de nincsen elég erőforrás, akkor kénytelen addig várni, amíg A folyamat fel nem szabadítja az 5. osztály erőforrásait. B vagy C csak akkor mehet tovább. Amíg B és C vár, addig A-nak nem kell várnia B-re vagy C-re, így nem alakul ki a ciklikus várakozás.
A rendszer akkor hatékony, ha a sorszámat jól osztjuk ki. Sajnos ez nem mindig teljesíthető feltétel.
A bankár algoritmus alapelve az, hogy csak akkor enged egy foglalási igényt kielégíteni, ha az a rendszert "biztonságos állapotban" tartja. Egy állapotot akkor tekintünk biztonságosnak, ha létezik egy olyan lépés sorozat, amelyben az összes folyamat erőforrásigénye kielégíthető.
Az algoritmus akkor működik, ha a folyamatok indulásukkor tudják, hogy a különböző típusú erőforrásokból mekkora a maximális igényük és azt be is jelentik az erőforráskezelőnek egy rendszerhíváson keresztül.
A bankár algoritmus a valóságos kérések bejövetelekor megvizsgálja, hogy mi történne, ha a kérést kielégítené, a rendszer biztonságos marad-e? Ha igen, akkor az igényt kielégíti, ha nem, akkor a folyamat várakozó listára kerül. Amikor egy folyamat visszad egy erőforrást, akkor az erőforráskezelő végignézi a várakozólistán lévő folyamatokat, hogy van-e olyan, amelyiknek az igénye kielégíthető. Mivel a várakozó folyamatokat csak engedi futni a rendszer, ha az igényeik kielégíthetőek, ezért nem alakul ki holtpont.
Az algoritmus nem a holtpontnál tágabb helyzetben akadályozza meg esetleg folyamatok futását, ezért mondhatjuk, hogy túlzott biztonságra tör.
Az algoritmusnak vigig kell "játszania" az éppen kérést igénylő folyamatok adatai alapján a lehetőségeket és csak akkor szabad egy folyamatot beengednie a kielégített folyamatok közé, ha biztonságos állapotban marad a rendszer, ez azonban sokszor időigényes feladat.
A holtpont feltételeinek kialakulása nem jelent egyértelműen holtpontot, azonban vannak esetek, amikor a holtpont kialakulását nem lehet megelőzni. Az első feladat az, hogy felismerjük a holtpontot.
Az operációs rendszer folyamatosan nyilvántartja a kiosztott erőforrásokat, a szabad erőforrásokat és a ki nem elégített igényeket. A holtpont felismerő algoritmusok egyike a bankár algoritmushoz hasonló , a ásik a foglaltsági gráf hurokmentességét ellenőrzi.
A holtpont detektáló algoritmus lefuttatása időigényes folyamat, ezért lefuttatása lassítja a rendszert. Nem célszerű lefuttsatni minden esetben, amikor a rendszer egy erőforrásigényt nem tud azonnal kielégíteni, hiszen ez nem jelent feltétlenül hotlpontot. A megoldás az, hogy viszonylag ritkán, megadott időnként futtatjuk le, amely azonban magábanrejti azt a veszélyt, hogy egyes folyamatok már régóta holtponti ciklusban vannak, mire felismerjük az állapotot.
A felismert holtpont megszüntetésének legegyszerűbb módja, az összes folyamat leállítása, de ez hatalmas veszteségekkel járhat, ezért célszerűbb a holtpontban résztvevő folyamatok egyikét leállítani, és ellenőrizzük le, hogy a maradék folyamatok holtpontban vannak-e? Ha nem, akkor újabb áldozatot választunk. A végén legalább egy folyamat megússza!
Hogyan válasszuk ki az áldozatunkat? Csakis kompromisszmos megoldás jöhet szóba. Milyen szempontok szerint válasszunk?
Mennyit nyerek? - Lőjük ki a sok erősorrást lefoglaló folyamatot, sok erőforrás felszabadul, valószínűleg ki lehet elégíteni a várakozókat.
Mennyi erőforrást igényel még? - A nagy erőforrásigényű folyamat valószínűleg újabb holtpontot fog okozni.
Mennyi CPU idpt és I/O munkát vesztünk a megszüntetéssel? Olyat válasszunk, amelynél kevés a veszteség.
Mennyi idő van még hátra a futásából? Ha kevés, akkor célszerű azt befejezni.
Ismételhető-e a folyamat. Ne olyat válasszunk, amely nem ismételhető.
Prioritás. Kisebb prioritású folyamatot válasszunk!
Megszüntetése hány további folyamat megszüntetését vagy hosszas várakozását idézi elő?
Előfordulhat, hogy a folyamatokat nem kell leállítani, hanem csak elvenni tőlük bizonyos erőforrásokat. A gyakorlatban persze az erőforrás erőszakos elvétele helyrehothatatlan hibákhoz vezet, azaz a helyzet nem változik lényegesen.
Gyakran elegendő a folyamatokat egy korábbi állapotukba visszavinni. Ehhez az állapotokat rendszereen el kell menteni, ellenőrző pontokat (check points) kell használni. Így a foyamatok felélesztése kisebb veszteséggel jár, de nagy memória és háttértár kapacitás kell, továbbá lelassul a rendszer.
Ha a holtpontkezelés során sokszor ugyanazt a folyamatot választjuk áldozatnak, akkor itt is kialakuhat a kiéheztetés!
Közös erőforrásoknak nevezzük azokat az erőforrásokat, amelyeket több folyamat egy időben akar egyszerre használni. Ezek az esetek a kölcsönös kizárást igénylő erőforrásoknál fordulnak elő leggyakrabban, például nyomtató.
A kölcsönös kizárást igénylő erőforrások kezelését végző programokat kritikus szekciónak hívjuk. Az a cél, hogy a kritikus szekcióban egy időben csak egy folyamat tartózkodjon.
Termelő-fogyasztó probléma
Tegyük fel, hogy van két folyamat, amely közös memóriaterületen keresztül kommunikál egymással. Ezt a területet postaládának hívjuk. Az egyik folyamat - termelő folyamat - az adatokat beírja a közös memóriaterületre, a másik - fogyasztó folyamat - kiolvassa az adatokat. A postaláda, kölcsönös kizárást igénylő erőforrás, mert amíg a termelő, addig a fogyasztó nem olvashat és fordítva.
A vezérlés megoldása szemaforokkal történik. A szemafort mind a termelő, mind a fogyasztó folyamat eléri. A szemafor értéke 1, akkor tilosat mutat, ha 0, akkor szabadot. Ezt bináris szemafornak hívjuk.
A termelő folyamat kiolvassa a szemafor értékét. Ha szabad, akkor tilosra állítjuk, és írhatunk a postaládába, majd az írás végén szabadra állítjuk a szemafort. Ha tilos volt, akkor rövid várakozás után újra megnézzük a szabad jelzést.
A fogyasztó folyamat ugyanilyen algoritmussal dolgozik.
Ennek a megoldásnak az a hátulütője, hogy ha a két folyamat közel egyszerre olvassa ki a szemafort, akkor mindekettő szabadnak vélvén elkezdi használni a postaládát. A hiba oka az, hogy a szemafor tesztje és a szemafor állítása között idő telt el.
Az egyik megoldás az, hogy a számítógépek processzorainak van hasonló műveletsort végző TEST AND SET gépi utasítása. Az utasítás beolvassa egy regiszterbe az adott emóriaterület értékét, majd tilosra állítja a memóriatartalmat. Ezután vizsgálja a regiszter tartalmát.
Másik lehetőség, főleg egy feladatos rendszerekben ha csak megszakítáokkal dolgoznak együtt a folyamatok, hogy az elsp lépése bármelyik folyamatnak a megszakítás tiltása, majd a folyamat végén a megszakítás engedélyezése.
Más lehetőség a memóriahozzáférés lock-olása, lezárása.
A többfeladatos rendszerekben az ilyen kérdések nagyon gyakoriak, ezért már Dijkstra (Holland programozó, elméleti szakember) néhány évtizeddel ezelőtt megoldotta a problémát a P és V primitívek formájában.
A P primitív a szemafor lefoglalását végzi, míg a V primitív a felszabadítását. (A primitív az operációs rendszer oszthatatlan, "atomi", legkisebb műveleteit jelenti). Valójában ezek függvények, amelyeknek a vizsgált szemafort kell megadni paraméterül. A primitível a teljes folgalást és a várakozási ciklusokat is tartalmazzák.
Nyilvánvaló, hogy a primitívek segítségével tetszőleges számú és fajtájú erőforrás kezelhető, csak arra kell vigyázni, hogy a folyamatok elérjék a megfelelő memóriaterületeket
Ha a primitív nem csak 0-t és e1-est ír a szemaforba, hanem növeli vagy csökkenti az ott lévő értéket, akkor módosított P és V primitívről beszélünk.
Torlódásvezérlő szemaforok
Ha a szemaforba nem csak 0 és 1 értéket írhatunk be, hanem az értékét eggyel növelhetjük vagy csökkenthetjük, akkor alkalmas eszközünk van többértékű erőforrások kezelésére. A fenti példában ha a postaládába többlevélnek van hely. Ilyenkor két új szemafort rendelünk a postaládához, az un. Torlódásvezérlő szemaforokat. Az egyik a szaba helyek számát mutatja, a másik az teli helyek számát. Az ilyen többértékű szemaforok a nembináris szemaforok.
A fentiek alapján a módosított P és V primitívek tuják kezelni a nembináris szemaforokat.
Egyelőre itt van az elméleti rész vége.
Dijkstra-féle szemafor és a T.H.E. architectúra:
- A T.H.E. architektúra és rétegei
Taskrendszerek determinizmusa:
- Taszkok állapotai; az állapotváltozások okai
- Taszkvezérlési folyamatok módjai
Szinkronizáció elve:
- Szinkron folyamatok fogalma
- Elve, lényege ; ugrótábla fogalma
- A prioritás sorrendképző szerepe
Rendszerhívások mechanizmusa:
- Rendszerhívások elérésének lehetősége a különböző programozási nyelvekben
- Perifériakezelések módjai
- Primitívként és folyamatként futó funkciók működése
- Elnevezések, fogalmak
- Tárvédelmek
Memória-hierarchia:
- Lineáris címterületű memória
- Memóriaszervezés tárbankok alkalmazásával
- Virtuális tár
Relokáció fogalma:
- Elve, lényege
- Fizikai cím, logikai (relativ) cím kapcsolata
- Relokációs bázisregiszter fogalma
- Memória tömörítés
Lapozási stratégiák:
- Logikai lap, lapméret, laptábla
- Virtuális tár
- Lapcsere algoritmusok
Abszolút címzésű rendszerek:
- Tárfelosztás
- Közvetlen címzés
- Határregiszter fogalma
Áthelyezhető címzésű rendszerek:
- Relativ címzés elve, lényege
- Szegmentálás, kódmegosztás
- Tranziens memóriarészű tár
- Dinamikus áthelyezés
Fájl megosztás, elérési és egyéb jogosultságok:
- Fa-struktúra; link
Hálózati alapú fájlszerver:
- Elosztott rendszerek hozzáférései
Találat: 3079