Operációs rendszerek. 4. gyakorlat: Szignálok küldése, kezelése

Hasonló dokumentumok
Jelzések és kezelésük

OPERÁCIÓS RENDSZEREK 1. PROCESSZKEZELÉS

UNIX folyamatok kommunikációja

OPERÁCIÓS RENDSZEREK. A mai program. Hiba és eseménykezelés. Alapfogalmak. Eseménykezelés, szignálozás

UNIX folyamatok kommunikációja

Operációs rendszerek 1.

Operációs rendszerek. 6. gyakorlat: Processzusok közti kommunikáció (osztott memória, üzenetsor)

A függvény kód szekvenciáját kapcsos zárójelek közt definiáljuk, a { } -ek közti részt a Bash héj kód blokknak (code block) nevezi.

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Függvények. Dr. Bécsi Tamás 6. Előadás

Mintavételes szabályozás mikrovezérlő segítségével

C programozási nyelv

Programozás alapjai C nyelv 4. gyakorlat. Mit tudunk már? Feltételes operátor (?:) Típus fogalma char, int, float, double

C programozás. 1 óra Bevezetés

Függvény pointer. Feladat: Egy tömbben soroljunk fel függvényeket, és hívjuk meg valahányszor.

Programozás I gyakorlat. 10. Stringek, mutatók

Uniprogramozás. várakozás. várakozás. Program A. Idő. A programnak várakoznia kell az I/Outasítások végrehajtására mielőtt továbbfuthatna

Folyamatok kezelése. Az operációs rendszerek egyik legfontosabb feladata a folyamatok kezelése.

Konkurens TCP Szerver

OPERÁCIÓS RENDSZEREK II GYAKORLAT

Programozás I. gyakorlat

6. fejezet: Ciklusok

Operációs rendszerek

Programozás 6. Dr. Iványi Péter

Szkriptnyelvek. 1. UNIX shell

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

Függvények. Programozás I. Hatwágner F. Miklós november 16. Széchenyi István Egyetem, Gy r

Programzás I gyakorlat

Programozás C++ -ban 2007/7

Járműfedélzeti rendszerek II. 3. előadás Dr. Bécsi Tamás

Concurrency in Swing

A MATLAB alapjai. Kezdő lépések. Változók. Aktuális mappa Parancs ablak. Előzmények. Részei. Atomerőművek üzemtana

Operációs rendszerek. Folyamatok kezelése a UNIX-ban

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

Programozás II. 2. Dr. Iványi Péter

Adatbázis rendszerek Gy: Algoritmusok C-ben

A programozás alapjai

Programozás 1. Dr. Iványi Péter

Programozás I. 5. Előadás: Függvények

Processzusok (Processes), Szálak (Threads), Kommunikáció (IPC, Inter-Process Communication)

UNIX: folyamatok kommunikációja

Operációs rendszerek MINB240

Már megismert fogalmak áttekintése

A programozás alapjai 1 Rekurzió

Processzusok (Processes), Szálak (Threads), Kommunikáció (IPC, Inter-Process Communication)

Mit tudunk már? Programozás alapjai C nyelv 4. gyakorlat. Legnagyobb elem keresése. Feltételes operátor (?:) Legnagyobb elem keresése (3)

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

Objektumorientált programozás Pál László. Sapientia EMTE, Csíkszereda, 2014/2015

Operációs rendszerek MINB240

Socket programozás Példák

alarm MICROALARM KFT Budapest, Kende u. 1. Tel.: ,

Thermo1 Graph. Felhasználói segédlet

Az operációs rendszer szerkezete, szolgáltatásai

Programozás C nyelven FELÜLNÉZETBŐL elhullatott MORZSÁK. Sapientia EMTE

Matematikai és Informatikai Intézet. 4. Folyamatok

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Mutatók. Dr. Bécsi Tamás 7. Előadás

LINUX PMB LINUXOS PARANCSOK ÉS HASZNÁLATUK - GRUB

1. Alapok. Programozás II

Operációs rendszerek Folyamatok 1.1

NAV felé történő számla adatszolgáltatás a Nagy Utazás 3 programmal

1. oldal összesen 6 oldal FARFISA TD6100 DIGITÁLIS NYOMÓGOMB PANEL

Programozás C és C++ -ban

Unix-Linux alapok II. gyakorlatvezető: Lutár Patrícia

Programozás 5. Dr. Iványi Péter

C# Szálkezelés. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) C# Szálkezelés / 21

Windows há lo záti ádminisztrá cio gyákorlát

Miről lesz ma szó? A PROGAMOZÁS ALAPJAI 1. Dinamikus változók. Dinamikus változók. Dinamikus változók. Dinamikus változók. 7.

INFORMATIKAI ALAPISMERETEK

Informatika terméktervezőknek

A C programozási nyelv V. Struktúra Dinamikus memóriakezelés

Operációs rendszerek. Az NT folyamatok kezelése

Osztályok. 4. gyakorlat

Hardver és szoftver követelmények

Rekurzió. Dr. Iványi Péter

Programozás I. 1. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

A C programozási nyelv II. Utasítások. A függvény.

C programozás. 6 óra Függvények, függvényszerű makrók, globális és

Óbudai Egyetem. C programozási nyelv

Szkriptnyelvek II. Perl programok

A C programozási nyelv VI. Parancssori argumentumok File kezelés

Programozás II. ATM példa Dr. Iványi Péter

Függvények. Programozás alapjai C nyelv 7. gyakorlat. LNKO függvény. Függvények(2) LNKO függvény (2) LNKO függvény (3)

7. Laboratóriumi gyakorlat: Vezérlési szerkezetek II.

Programozás alapjai C nyelv 7. gyakorlat. Függvények. Függvények(2)

Pénzügyi algoritmusok

Járműfedélzeti rendszerek II. 2. előadás Dr. Bécsi Tamás

chmod umask chown, chgrp

Szenzorhálózatok programfejlesztési kérdései. Orosz György

Programozás. Programozás villamosmérnököknek

Programozási nyelvek I. 5. előadás (Gregorics Tibor anyagának felhasználásával)

Matlab alapok. Baran Ágnes. Baran Ágnes Matlab alapok Elágazások, függvények 1 / 15

Programozás alapjai C nyelv 5. gyakorlat. Írjunk ki fordítva! Írjunk ki fordítva! (3)

Bevezetés a számítógépes rendszerekbe programozóknak

8. gyakorlat Pointerek, dinamikus memóriakezelés

A C programozási nyelv I. Bevezetés

Cekla. Készítette Doxygen Tue Sep :13:44

A C programozási nyelv I. Bevezetés

Programozási alapismeretek beadandó feladat: ProgAlap beadandó feladatok téma 99. feladat 1

Dr. Schuster György október 14.

A függvények névvel rendelkező utasításcsoportok, melyeknek információkat adhatunk át, és van egy visszatérési értékük.

S z á m í t ó g é p e s a l a p i s m e r e t e k

Átírás:

Operációs rendszerek 4. gyakorlat: Szignálok küldése, kezelése Ajánlott irodalom UNIX programozáshoz: Kernighan & Pike: A Unix operációs rendszer Stewens: Advanced Programming in the UNIX Environment (APUE) Unix Programming FAQ http://www.erlenstar.demon.co.uk/unix/ A UNIX processzusokat a rendszert érő külső hatásokról (pl. lebegőpontos hiba, programhibák, hardver események) un. jelek szignálok értesítik. A szignál egy állapotjelző, mely a címzett processzusban kiváltja a kezelést végző függvény meghívását. A UNIX rendszereken 63 különböző szignál használható, melyekről részletesen a man-ból tájékozódhatunk (linux rendszereken: man 7 signal). Ha egy processzus nem definiál szignál kezelőt egy adott szignálhoz, akkor a rendszer egy alapértelmezett kezelővel fogja kezeltetni a szignált. Fontos tisztában lenni azzal, hogy melyik szignálnak mit tesz az alapértelmezett kezelője. A szignál kezelésének fontos tulajdonsága, hogy ha egy processzus saját kezelőt használ, akkor az csak az minden szignál kezelése után visszaáll az alapértelmezett kezelőre. Ez a magyarázata annak is, hogy bizonyos esetekben (pl. rendszer leállítása) a processzusoknak két TERM szignált kell küldeni: az elsőt a program kezeli, a másodikra, pedig az alapértelmezett kezelő reagál. Ez alól kivételt képeznek a BSD 4.4-et kötető rendszerek (így a Linux is a glibc2 verzió óta). Ezeken a rendszereken nem áll vissza az alapértelmezett kezelő, viszont a rendszer gondoskodik arról, hogy a szignál kezelő futását ugyanolyan szignál nem szakíthatja meg.

Tekintsünk át néhány fontos szignált és alapértelmezett kezelést: Szignál SIGHUP (HangUp) Alapértelmezett kezelés Processzus befejezése Esemény Eredetileg: a terminál telefonvonalának bontása. Ma: gyakran daemon processzusok konfigurációjának ujraolvasása. SIGINT (Interrunpt) SIGTERM (Terminate) SIGKILL (Kill) Processzus befejezése Billentyűzetről kiadott megszakítás (Ctrl+C) Processzus befejezése A program szabályos leállítása (mentéssel) Processzus befejezése A program azonnali leállítása (mentés nélkül) SIGSEGV (Segmentation Violation) SIGCHLD (Child terminated) SIGSTOP (Stop) Processzus befejezése és core dump készítése Szignál figyelmen kívül hagyása Processzus megállítása FONTOS: ez a szignál nem maszkolható és nem lehet megváltoztatni a kezelőjét!!! A processzus előző memóriahivatkozása érvénytelen volt. A processzus valamelyik gyermek processzusa befejeződött vagy megállítódott. A processzus ezután blokkolt állapotba kerül és nem lesz CPU-ra ütemezve. SIGTSTP (Terminal Stop) SIGCONT (Continue) SIGALRM (Alarm) FONTOS: ez a szignál nem maszkolható és nem lehet megváltoztatni a kezelőjét!!! Processzus megállítása A processzus ezután blokkolt állapotba kerül és nem lesz CPU-ra ütemezve. Ezt a szignált billentyűzetről lehet küldeni (Ctrl+Z). Processzus folytatása A processzus ezután futásra kész állapotba kerül és ütemezésre vár. Processzus befejezése Az OS időzítője küldi a kérő processzusnak, a megadott idő lejárta után.

Szignálok küldése Alapvető szabály, hogy egy felhasználó processzusa, csak ugyanannak a felhasználónak a processzusának küldhet szignált. Ez alól kivételt csak a rendszergazda processzusai képeznek, melyek bármely processzusnak küldhetnek szignálokat. Ha valaki szignált szeretne küldeni, akkor tudnia kell, hogy mit akar küldeni, és hogy kinek akarja küldeni. Az összes olyan processzusnak, ami egy adott bináris fájlt futtat, küldhetünk egy szignált az alábbi parancssori utasítással: $ killall <signal> <process> Ezzel nem egyetlen szignált küldtünk, hanem annyit ahány processzus futott. Egyetlen processzusnak küldhetünk a parancssorból a $ kill <signal> <PID> utasítással. Szignálok programból való küldésére az operációs rendszer két függvényt is biztosít az ANSI C programozónak. A kill() függvény #include <sys/types.h> int kill(pid_t pid, int sig); A függvény viselkedése: Ha mindkét argumentum pozitív szám, akkor a sig számú szignált elküldi a pid számú processzusnak. Ha a pid nulla, akkor a sig szignált elküldi minden processzusnak, ami ugyanabban a processzus csoportban van, mint a küldő. (Processzus csoportokkal később foglalkozunk!) Ha a pid pontosan -1, akkor az első processzus kivételével mindegyiknek elküldi a sig szignált.

Ha a pid kisebb -1 nél, akkor a pid azonosítójú processzus csoport minden tagja megkapja. Ha a sig argumentum nulla, akkor nem küld szignált, csak ellenőrzi, hogy küldhetne-e. Visszatérési értéke 0, ha sikeres volt a küldés és -1, ha sikertelen. Sikertelen küldés esetén az errno változó tartalmazza a hiba kódját. A raise() függvény int raise(int sig); Ez a függvény annyiban tér el a kill() függvénytől, hogy csak annak a processzusnak küldi a szignált, amelyik a függvényt meghívta. Szignálok kezelése Ha egy programban egy szignált szeretnénk egyedileg kezelni, akkor erről értesíteni kell az operációs rendszert. Ezt a cég szolgálja a signal() függvény. typedef void (*signalhandler_t)(int); signalhandler_t signal(int sig, siganlhandler_t handler); A függvény a megadott sig szignál kezelőjét átállítja a handler által mutatott függvényre. Visszatérési értéke az adott szignál előző kezelője, vagy a SIG_ERR konstans, ha hiba történt A kezelőfüggvény argumentumában megkapja a szignál számát, így egy kezelő függvény lehet több szignál kezelője is.

Végezetül nézzük meg az alábbi példa programot és próbáljuk ki azt több operációs rendszeren is (Linux, Solaris, AiX, stb.), különböző szignálokra is! #include <stdio.h> #include <sys/types.h> void kezelo(int i) printf("signal kezelese: %d\n", i); return; } int main( void ) printf("pid = %d\n", getpid()); printf("signal kezelo atvetele: %d\n", signal(sigterm, &kezelo)); while (1) printf("lepes\n"); sleep(3); } } Szignálok használata időzítésre Ha egy programban az eseményeket késleltetni akarjuk, régen (Pascalban) egy delay eljárással megtehettük ezt. Ez az eljárás gyakorlatilag egy megadott ideig futó üres ciklus. Multiprogramozású rendszereken késleltetésest nem célszerű üres ciklussal megoldani, mivel az fölöslegesen rabolja az CPU idejét más processzusok elől, ráadásul az ütemezés miatt nem ad pontos időzítést ez a módszer. Előnyösebb és pontosabb módszer, ha megbízzuk az operációs rendszert, hogy bizonyos idő múlva küldjön egy szignált a processzusunknak, amit addig akár blokkolhatunk is.

Erre való az alarm() függvény, ami megbízza az operációs rendszert, hogy megadott idő múlva küldjön a hívó processzusnak egy SIGALRM szignált. unsigned int alarm(unsigned int seconds); Ha a függvény seconds argumentumában nem nulla, akkor megadott másodpercek letelte után kap a processzus egy SIGALRM szignált. A visszatérési értékben visszakapjuk, hogy mennyi idő múlva kaptunk volna szignált az előző beállítás alapján. Ha nullát kapunk, akkor nem volt előző beállítás. Ha az argumentumban nullát adunk, akkor nem állít be időzítést, csak lekérdezésre használjuk. Miután beállítottuk az ébresztést a program tehet bármit. Ha nincs mit tenni, akkor lemondatjuk a CPU-ért való versengésről, azaz blokkoljuk a processzust. Ezt többféleképpen érhetjük el: Küldhetünk a saját processzusnak egy SIGSTOP (vagy SIGTSTP) szignált raise (SIGSTOP); vagy használhatjuk a pause() függvényt. int pause(); Ennek a függvénynek nem adunk semmilyen argumentumot. Hatására a processzus ebben a hívásban blokkolódik, amíg egy szignál futásra kész állapotba nem billenti. A visszatérési értéke a kapott szignál száma. Így 20 mp-es késleltetést az alábbi módon oldhatunk meg: for (alarm(20); pause()!= SIGALRM;);

vagy int wakeup_sgn = 0; alarm(20); do wakeup_sgn = pause(); } while (wakeup_sgn!= SIGALRM); Ha a cél csak annyi, hogy várakoztassuk a processzust, akkor ezt egyetlen függvényhívással is megvalósíthatjuk. Ezt a célt szolgálja a sleep() függvény. unsigned int sleep(unsigned int seconds); A processzus a hívásban a megadott seconds másodpercig blokkolódik, majd felébred. Mivel blokkolt állapotból egy processzust minden szignál felébreszt, ezért a függvényből való kilépéskor a visszatérési érték adja meg, hogy hány másodperc maradt hátra a kért időzítésből. Ha nullát kapunk, akkor letelt az időzítés. Fontos tudni, hogy nincs szabványban rögzítve, hogyan kell implementálni ezt a függvényt, így előfordulhat (sőt gyakori), hogy az alarm() és pause() függvényekkel van implementálva, valahogy úgy, ahogy az előbb tettük. Emiatt erősen ellenjavallott a sleep() függvénynek a alarm() és pause() függvényekkel való együttes használata!