103.6 Lecke 1
Tanúsítvány: |
LPIC-1 |
---|---|
Verzió: |
5.0 |
Témakör: |
103 GNU és Unix parancsok |
Fejezet: |
103.6 A folyamatok végrehajtási prioritásának módosítása |
Lecke: |
1/1 |
Bevezetés
Az egynél több folyamat egyidejű futtatására képes operációs rendszereket többfeladatos vagy többprocesszoros rendszereknek nevezzük. Míg a valódi egyidejűség csak akkor valósul meg, ha egynél több feldolgozóegység (processing unit) áll rendelkezésre, az egyprocesszoros rendszerek is képesek szimulálni az egyidejűséget azáltal, hogy nagyon gyorsan váltanak a folyamatok között. Ezt a technikát alkalmazzák a sok egyenértékű processzorral rendelkező rendszerekben, vagy szimmetrikus többprocesszoros (SMP) rendszerekben is, mivel a lehetséges egyidejű folyamatok száma jóval meghaladja a rendelkezésre álló processzoregységek számát.
Valójában egyszerre csak egy folyamat irányíthatja a CPU-t. A legtöbb folyamat tevékenysége azonban rendszerhívás (system call), azaz a futó folyamat átadja a CPU-irányítást az operációs rendszer valamelyik folyamatának, hogy az elvégezze a kért műveletet. A rendszerhívások felelősek minden eszközök közötti kommunikációért, például a memóriafoglalásokért, a fájlrendszerekből történő olvasásért és írásért, a képernyőre történő szövegmegjelenítésért, a felhasználói interakciókért, a hálózati átvitelért, stb. A CPU-vezérlés átadása egy rendszerhívás során lehetővé teszi az operációs rendszer számára annak eldöntését, hogy visszaadja-e a CPU-vezérlést az előző folyamatnak, vagy átadja-e azt egy másiknak. Mivel a modern CPU-k sokkal gyorsabban képesek utasításokat végrehajtani, mint ahogy a legtöbb külső hardver kommunikálni tud egymással, egy új vezérlőfolyamat sok CPU-munkát végezhet el, miközben a korábban kért hardverválaszok még mindig nem állnak rendelkezésre. A CPU maximális kihasználásának biztosítása érdekében a többprocesszoros operációs rendszerek dinamikus sorban tartják az aktív folyamatokat, amelyek CPU-időre várnak.
Bár ezek lehetővé teszik a CPU-idő kihasználtságának jelentős javítását, a folyamatok közötti váltás kizárólag a rendszerhívásokra támaszkodva nem elegendő a kielégítő többfeladatos teljesítmény eléréséhez. Egy olyan folyamat, amely nem hajt végre rendszerhívásokat, a végtelenségig irányíthatja a CPU-t. Ezért a modern operációs rendszerek preemptívek is, azaz egy futó folyamatot vissza lehet tenni a sorba, hogy egy fontosabb folyamat irányíthassa a CPU-t, még akkor is, ha a futó folyamat nem hajtott végre rendszerhívást.
A Linux ütemezője
A Linux, mint preemptív többprocesszoros operációs rendszer, egy ütemezőt (scheduler) valósít meg, amely a folyamatok sorát szervezi. Pontosabban az ütemező dönti el azt is, hogy melyik sorba állított szál (thread) kerüljön végrehajtásra — egy folyamat több független szálra is elágazhat — de a folyamat és a szál ebben a kontextusban felcserélhető fogalmak. Minden folyamatnak két predikátuma van, amely beavatkozik az ütemezésébe: az ütemezési irányelv (scheduling policy) és az ütemezési prioritás (scheduling priority).
Az ütemezési irányelveknek két fő típusa van: valós idejű irányelvek és általános irányelvek. A valós idejű irányelvek alá tartozó folyamatok ütemezése közvetlenül a prioritási értékük alapján történik. Ha egy fontosabb folyamat készen áll a futtatásra, egy kevésbé fontos futó folyamatot megelőz és a magasabb prioritású folyamat átveszi a CPU feletti irányítást. Egy alacsonyabb prioritású folyamat csak akkor kapja meg a CPU irányítását, ha a magasabb prioritású folyamatok üresjáratban vannak vagy hardveres válaszra várnak.
Minden valós idejű folyamat magasabb prioritással rendelkezik, mint egy normál folyamat. Általános célú operációs rendszerként a Linux csak néhány valós idejű folyamatot futtat. A legtöbb folyamat, beleértve a rendszer- és felhasználói programokat is, normál ütemezési szabályok szerint fut. A normál folyamatok általában azonos prioritási értékkel rendelkeznek, de a normál házirendek egy másik folyamatpredikátummal: a nice value (jó érték) segítségével határozhatják meg a végrehajtási prioritási szabályokat. A nice értékekből származtatott dinamikus prioritásokkal való összetévesztés elkerülése érdekében az ütemezési prioritásokat általában statikus ütemezési prioritásoknak nevezik.
A Linux ütemezője sokféleképpen konfigurálható, és a prioritások megállapításának még bonyolultabb módjai is léteznek, de ezek az általános fogalmak mindig érvényesek. A folyamatok ütemezésének vizsgálatakor és hangolásakor fontos szem előtt tartani, hogy csak a normál ütemezési irányelvek alá tartozó folyamatokat érinti.
Prioritások ellenőrzése
A Linux 0 és 99 közötti statikus prioritásokat tart fenn a valós idejű folyamatok számára, a normál folyamatok pedig 100 és 139 közötti statikus prioritásokat kapnak, ami azt jelenti, hogy a normál folyamatok számára 39 különböző prioritási szint létezik. Az alacsonyabb értékek magasabb prioritást jelentenek. Egy aktív folyamat statikus prioritása a sched
fájlban található, a /proc
fájlrendszeren belül a megfelelő mappában:
$ grep ^prio /proc/1/sched prio : 120
Ahogy a példában látható, a prio
kezdetű sor a folyamat prioritási értékét adja meg (a PID 1 folyamat a init vagy systemd folyamat, az első folyamat, amelyet a kernel a rendszer inicializálása során elindít). A normál folyamatok szabványos prioritása 120, így ez 100-ra csökkenthető vagy 139-re növelhető. Az összes futó folyamat prioritása ellenőrizhető a ps -Al
vagy ps -el
paranccsal:
$ ps -el F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 9292 - ? 00:00:00 systemd 4 S 0 19 1 0 80 0 - 8817 - ? 00:00:00 systemd-journal 4 S 104 61 1 0 80 0 - 64097 - ? 00:00:00 rsyslogd 4 S 0 63 1 0 80 0 - 7244 - ? 00:00:00 cron 1 S 0 126 1 0 80 0 - 4031 - ? 00:00:00 dhclient 4 S 0 154 1 0 80 0 - 3937 - pts/0 00:00:00 agetty 4 S 0 155 1 0 80 0 - 3937 - pts/1 00:00:00 agetty 4 S 0 156 1 0 80 0 - 3937 - pts/2 00:00:00 agetty 4 S 0 157 1 0 80 0 - 3937 - pts/3 00:00:00 agetty 4 S 0 158 1 0 80 0 - 3937 - console 00:00:00 agetty 4 S 0 160 1 0 80 0 - 16377 - ? 00:00:00 sshd 4 S 0 280 0 0 80 0 - 5301 - ? 00:00:00 bash 0 R 0 392 280 0 80 0 - 7221 - ? 00:00:00 ps
A PRI
oszlop a kernel által kiosztott statikus prioritást jelzi. Figyeljük meg azonban, hogy a ps
által megjelenített prioritás értéke eltér az előző példában kapott értéktől. Történelmi okok miatt a ps
által megjelenített prioritások alapértelmezés szerint -40 és 99 között mozognak, így a tényleges prioritást úgy kapjuk meg, hogy hozzáadunk 40-et (80 + 40 = 120).
Lehetőség van a Linux kernel által jelenleg kezelt folyamatok folyamatos megfigyelésére is a top
programmal. A ps
-hez hasonlóan a top
is másképp jeleníti meg a prioritás értékét. A valós idejű folyamatok könnyebb azonosítása érdekében a top
a prioritás értékét 100-zal csökkenti, így minden valós idejű prioritás negatív lesz, és egy negatív szám vagy rt jelöli őket. Ezért a top
által megjelenített normál prioritások 0-tól 39-ig terjednek.
Note
|
A $ ps -e -o user,uid,comm,tty,pid,ppid,pri,pmem,pcpu --sort=-pcpu | head |
Processzek jósága (niceness)
Minden normál folyamat alapértelmezett 0-s nice értékkel (120-as prioritás) indul. A nice név abból az elképzelésből ered, hogy a “szebb” folyamatok lehetővé teszik, hogy más folyamatok előttük fussanak egy adott végrehajtási sorban. A nice számok -20-tól (kevésbé nice, magas prioritás) 19-ig (magasabb nice, alacsony prioritás) terjednek. A Linux azt is lehetővé teszi, hogy ugyanazon folyamaton belül különböző nice értékeket rendeljünk a szálakhoz. A ps
kimenet NI
oszlopa a nice számot jelzi.
Csak a root felhasználó csökkentheti a folyamatok nice értékét nulla alá. Lehetőség van arra, hogy egy folyamatot nem szabványos prioritással indítsunk el a nice
paranccsal. Alapértelmezés szerint a nice
a niceness-t 10-re változtatja, de ez a -n
kapcsolóval megadható:
$ nice -n 15 tar czf home_backup.tar.gz /home
Ebben a példában a tar
parancsot 15-ös niceness-szel hajtjuk végre. A renice
paranccsal egy futó folyamat prioritását lehet megváltoztatni. A -p
kapcsoló a célfolyamat PID-számát adja meg. Például:
# renice -10 -p 2164 2164 (process ID) old priority 0, new priority -10
A -g
és -u
kapcsolók egy adott csoport vagy felhasználó összes folyamatának módosítására szolgálnak. A renice +5 -g users
paranccsal a users csoport felhasználóinak tulajdonában lévő folyamatok nice értéke öttel nő.
A renice
mellett a folyamatok prioritása más programokkal is módosítható, például a top
programmal. A top főképernyőn a folyamatok nice értékét az r
, majd a folyamat PID-számának megadásával lehet módosítani:
top - 11:55:21 up 23:38, 1 user, load average: 0,10, 0,04, 0,05 Tasks: 20 total, 1 running, 19 sleeping, 0 stopped, 0 zombie %Cpu(s): 0,5 us, 0,3 sy, 0,0 ni, 99,0 id, 0,0 wa, 0,2 hi, 0,0 si, 0,0 st KiB Mem : 4035808 total, 774700 free, 1612600 used, 1648508 buff/cache KiB Swap: 7999828 total, 7738780 free, 261048 used. 2006688 avail Mem PID to renice [default pid = 1] PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 74232 7904 6416 S 0,000 0,196 0:00.12 systemd 15 root 20 0 67436 6144 5568 S 0,000 0,152 0:00.03 systemd-journal 21 root 20 0 61552 5628 5000 S 0,000 0,139 0:00.01 systemd-logind 22 message+ 20 0 43540 4072 3620 S 0,000 0,101 0:00.03 dbus-daemon 23 root 20 0 45652 6204 4992 S 0,000 0,154 0:00.06 wickedd-dhcp4 24 root 20 0 45648 6276 5068 S 0,000 0,156 0:00.06 wickedd-auto4 25 root 20 0 45648 6272 5060 S 0,000 0,155 0:00.06 wickedd-dhcp6
A PID to renice [default pid = 1]
üzenet jelenik meg, és alapértelmezés szerint az első felsorolt folyamat van kiválasztva. Egy másik folyamat prioritásának megváltoztatásához írjuk be annak PID-jét, és nyomjuk le az Enter billentyűt. Ekkor megjelenik a Renice PID 1 to value
üzenet (a kért PID számmal), és egy új nice értéket lehet hozzárendelni.
Gyakorló feladatok
-
Mi történik egy preemptív többfeladatos rendszerben, amikor egy alacsonyabb prioritású folyamat foglalja le a processzort, és egy magasabb prioritású folyamat sorban áll a végrehajtásra?
-
Nézzük az alábbi
top
-ot:top - 08:43:14 up 23 days, 12:29, 5 users, load average: 0,13, 0,18, 0,21 Tasks: 240 total, 2 running, 238 sleeping, 0 stopped, 0 zombie %Cpu(s): 1,4 us, 0,4 sy, 0,0 ni, 98,1 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 7726,4 total, 590,9 free, 1600,8 used, 5534,7 buff/cache MiB Swap: 30517,0 total, 30462,5 free, 54,5 used. 5769,4 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 171420 10668 7612 S 0,0 0,1 9:59.15 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:02.76 kthreadd 3 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_par_gp 8 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 mm_percpu_wq 9 root 20 0 0 0 0 S 0,0 0,0 0:49.06 ksoftirqd/0 10 root 20 0 0 0 0 I 0,0 0,0 18:24.20 rcu_sched 11 root 20 0 0 0 0 I 0,0 0,0 0:00.00 rcu_bh 12 root rt 0 0 0 0 S 0,0 0,0 0:08.17 migration/0 14 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/0 15 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/1 16 root rt 0 0 0 0 S 0,0 0,0 0:11.79 migration/1 17 root 20 0 0 0 0 S 0,0 0,0 0:26.01 ksoftirqd/1
Mely PID-eknek van valós idejű prioritása?
-
Nézzük az alábbi
ps -el
listát:F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 42855 - ? 00:09:59 systemd 1 S 0 2 0 0 80 0 - 0 - ? 00:00:02 kthreadd 1 I 0 3 2 0 60 -20 - 0 - ? 00:00:00 rcu_gp 1 S 0 9 2 0 80 0 - 0 - ? 00:00:49 ksoftirqd/0 1 I 0 10 2 0 80 0 - 0 - ? 00:18:26 rcu_sched 1 I 0 11 2 0 80 0 - 0 - ? 00:00:00 rcu_bh 1 S 0 12 2 0 -40 - - 0 - ? 00:00:08 migration/0 1 S 0 14 2 0 80 0 - 0 - ? 00:00:00 cpuhp/0 5 S 0 15 2 0 80 0 - 0 - ? 00:00:00 cpuhp/1
Melyik PID-nek van magasabb prioritása?
-
Miután megpróbáltunk egy processzt renice-olni a
renice
segítségével, az alábbi hiba jelentkezik:$ renice -10 21704 renice: failed to set priority for 21704 (process ID): Permission denied
Mi a hiba legvalószínűbb oka?
Gondolkodtató feladatok
-
A folyamatprioritások megváltoztatására általában akkor van szükség, ha egy folyamat túl sok CPU-időt foglal le. A
ps
standard kapcsolókkal történő használata az összes rendszerfolyamatot hosszú formátumban írja ki, melyik--sort
flag rendezné a folyamatokat CPU kihasználtság szerint, növekvő sorrendben? -
A
schedtool
paranccsal beállíthatjuk az összes CPU ütemezési paramétert, amire a Linux képes, vagy megjeleníthetjük az adott folyamatokra vonatkozó információkat. Hogyan lehet vele megjeleníteni az1750
folyamat ütemezési paramétereit? Továbbá, hogyan lehet aschedtool
segítségével a 1750-es folyamatot -90-es prioritású valós idejűvé változtatni (ahogyan azt atop
mutatja)?
Összefoglalás
Ez a lecke azt tárgyalta, hogy a Linux hogyan osztja meg a CPU-időt a kezelt folyamatok között. A legjobb teljesítmény biztosítása érdekében a kritikusabb folyamatoknak meg kell előzniük a kevésbé kritikus folyamatokat. A leckében a következőkről volt szó:
-
Alapfogalmak a többprocesszoros rendszerekről.
-
Mi az a folyamatütemező és hogyan valósítja meg a Linux.
-
Mik a Linux prioritások, nice számok és mi a céljuk.
-
Hogyan olvassuk és értelmezzük a folyamatprioritásokat Linuxban.
-
Hogyan változtathatjuk meg egy folyamat prioritását a végrehajtás előtt és közben.
Válaszok a gyakorló feladatokra
-
Mi történik egy preemptív többfeladatos rendszerben, amikor egy alacsonyabb prioritású folyamat foglalja le a processzort, és egy magasabb prioritású folyamat sorban áll a végrehajtásra?
Az alacsonyabb prioritású folyamat szünetel, és helyette a magasabb prioritású folyamat kerül végrehajtásra.
-
Nézzük az alábbi
top
-ot:top - 08:43:14 up 23 days, 12:29, 5 users, load average: 0,13, 0,18, 0,21 Tasks: 240 total, 2 running, 238 sleeping, 0 stopped, 0 zombie %Cpu(s): 1,4 us, 0,4 sy, 0,0 ni, 98,1 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st MiB Mem : 7726,4 total, 590,9 free, 1600,8 used, 5534,7 buff/cache MiB Swap: 30517,0 total, 30462,5 free, 54,5 used. 5769,4 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 171420 10668 7612 S 0,0 0,1 9:59.15 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:02.76 kthreadd 3 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 rcu_par_gp 8 root 0 -20 0 0 0 I 0,0 0,0 0:00.00 mm_percpu_wq 9 root 20 0 0 0 0 S 0,0 0,0 0:49.06 ksoftirqd/0 10 root 20 0 0 0 0 I 0,0 0,0 18:24.20 rcu_sched 11 root 20 0 0 0 0 I 0,0 0,0 0:00.00 rcu_bh 12 root rt 0 0 0 0 S 0,0 0,0 0:08.17 migration/0 14 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/0 15 root 20 0 0 0 0 S 0,0 0,0 0:00.00 cpuhp/1 16 root rt 0 0 0 0 S 0,0 0,0 0:11.79 migration/1 17 root 20 0 0 0 0 S 0,0 0,0 0:26.01 ksoftirqd/1
Mely PID-eknek van valós idejű prioritása?
12 és 16.
-
Nézzük az alábbi
ps -el
listát:F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 1 0 0 80 0 - 42855 - ? 00:09:59 systemd 1 S 0 2 0 0 80 0 - 0 - ? 00:00:02 kthreadd 1 I 0 3 2 0 60 -20 - 0 - ? 00:00:00 rcu_gp 1 S 0 9 2 0 80 0 - 0 - ? 00:00:49 ksoftirqd/0 1 I 0 10 2 0 80 0 - 0 - ? 00:18:26 rcu_sched 1 I 0 11 2 0 80 0 - 0 - ? 00:00:00 rcu_bh 1 S 0 12 2 0 -40 - - 0 - ? 00:00:08 migration/0 1 S 0 14 2 0 80 0 - 0 - ? 00:00:00 cpuhp/0 5 S 0 15 2 0 80 0 - 0 - ? 00:00:00 cpuhp/1
Melyik PID-nek van magasabb prioritása?
12.
-
Miután megpróbáltunk egy processzt renice-olni a
renice
segítségével, az alábbi hiba jelentkezik:$ renice -10 21704 renice: failed to set priority for 21704 (process ID): Permission denied
Mi a hiba legvalószínűbb oka?
Csak a root tudja a nice számokat nulla alá csökkenteni.
Válaszok a gondolkodtató feladatokra
-
A folyamatprioritások megváltoztatására általában akkor van szükség, ha egy folyamat túl sok CPU-időt foglal le. A
ps
standard kapcsolókkal történő használata az összes rendszerfolyamatot hosszú formátumban írja ki, melyik--sort
flag rendezné a folyamatokat CPU kihasználtság szerint, növekvő sorrendben?$ ps -el --sort=pcpu
-
A
schedtool
paranccsal beállíthatjuk az összes CPU ütemezési paramétert, amire a Linux képes, vagy megjeleníthetjük az adott folyamatokra vonatkozó információkat. Hogyan lehet vele megjeleníteni az1750
folyamat ütemezési paramétereit? Továbbá, hogyan lehet aschedtool
segítségével a 1750-es folyamatot -90-es prioritású valós idejűvé változtatni (ahogyan azt atop
mutatja)?$ schedtool 1750
$ schedtool -R -p 89 1750