Co to takový proces vlastně je? Jedná se o každý spuštěný program v Linuxu, kterému systém po spuštění přidělí paměť a další systémové prostředky. Systémy Linux/Unix jsou víceúlohové a víceuživatelské, což znamená více procesů, z hlediska uživatele, běžících najednou. Není to tak úplně pravda, v jednoprocesorovém jednojádrovém procesoru běží v jeden okamžik pouze jeden proces. V systému je samozřejmě více procesů, které čekají na přidělení procesorového času. Toto přidělování řídí náš operační systém a není to jednoduchá věc, protože procesy mohou mít různé priority nebo být v různých stavech.
Výpis spuštěných procesů
My se podíváme, co vše můžeme s procesy dělat. Začneme jednoduchým výpisem procesů, k tomu slouží program ps
. Bez parametrů vypíše námi spuštěné procesy v právě používaném terminálu:
pm@pm-laptop:~/Documents$ ps PID TTY TIME CMD 2049 pts/1 00:00:00 bash 2105 pts/1 00:00:00 ps
Pomocí ps
můžeme získat mnohem více informací, proto použijeme další parametry, pro výpis všech procesů:
pm@pm-laptop:~/Documents$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 2624 1532 ? Ss 21:45 0:01 /sbin/init root 2 0.0 0.0 0 0 ? S< 21:45 0:00 [kthreadd] ... ... pm 1963 0.0 1.2 93968 12352 ? S 21:46 0:00 gnome-volume-control-applet ntp 1965 0.0 0.1 4228 1264 ? Ss 21:46 0:00 /usr/sbin/ntpd -p /var/run/ntpd.pid -u 114:123 -g pm 1972 0.0 0.3 18208 3072 ? Ss 21:46 0:00 gnome-screensaver root 1974 0.0 0.3 5844 3512 ? S 21:46 0:00 /usr/lib/policykit-1/polkitd pm 3605 0.0 0.1 5396 1784 pts/0 Ss 21:02 0:00 bash
Zobrazí se více sloupečků, v prvním je uživatel, který proces spustil. Pro nás bude důležitý druhý sloupec PID
. To je identifikátor procesu, pro každý proces to znamená jedinečné číslo. Později s ním budeme pracovat. Pak jsou tu údaje udávající zatížení CPU a paměti. Zajímavý může být třeba sloupec TTY, který udává terminál, v kterém je proces spuštěn. Proces nemusí být ale spuštěn vždy z nějakého terminálu (třeba při startu systému), pak zde bude znak ?. Další sloupec je stav procesu, např. R je právě běžící, T zastavený, … Zajímavý je proces označený písmenem Z (zombie). Pokud takové procesy vidíte, něco není dobře. Jedná se o proces, který je ukončený, ale jeho rodič se o něj nepostaral a neuklidil po něm. Kompletní seznam stavů se dočtete v man ps
.
Je možné si vypsat třeba procesy konkrétního uživatele nebo jakýsi strom procesů pomocí ps axjf
:
1 8340 1688 1688 ? -1 Rl 1000 0:22 gnome-terminal 8340 8341 1688 1688 ? -1 S 1000 0:00 \_ gnome-pty-helper 8340 8342 8342 8342 pts/0 8342 Ss+ 1000 0:00 \_ bash 8340 8442 8442 8442 pts/1 8465 Ss 1000 0:00 \_ bash 8442 8465 8465 8442 pts/1 8465 R+ 1000 0:00 \_ ps axjf
Lepší pohled na strom procesů nabídne program pstree
, jeho výpis se dá opět ovlivnit několika parametry, třeba:
$ pstree -pu ├─gnome-terminal(8340,pm)─┬─bash(8342)───pstree(8583) │ ├─bash(8442)───mc(8545)───bash(8547) │ ├─gnome-pty-helpe(8341) │ └─{gnome-terminal}(8343) ├─go-home-applet(1860,pm) ├─gvfs-fuse-daemo(1768,pm)─┬─{gvfs-fuse-daemo}(1769) │ ├─{gvfs-fuse-daemo}(1770) │ └─{gvfs-fuse-daemo}(1771) ├─gvfs-gdu-volume(1881,pm) ├─gvfs-gphoto2-vo(1922,pm) ├─gvfsd(1761,pm) ├─gvfsd-burn(1930,pm) ├─hald(487,haldaemon)───hald-runner(571,root)─┬─hald-addon-acpi(967,haldaemon) │ ├─hald-addon-cpuf(963) │ ├─hald-addon-gene(930) │ └─hald-addon-inpu(971)
Posledním programem, který si pro zobrazení procesů ukážeme, je program top
:
top - 12:54:21 up 2:11, 3 users, load average: 0.05, 0.08, 0.07 Tasks: 168 total, 2 running, 166 sleeping, 0 stopped, 0 zombie Cpu(s): 11.1%us, 4.8%sy, 0.0%ni, 80.8%id, 1.5%wa, 0.7%hi, 1.1%si, 0.0%st Mem: 1016796k total, 994564k used, 22232k free, 8408k buffers Swap: 1855468k total, 4352k used, 1851116k free, 664312k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2129 pm 20 0 114m 26m 11m S 11 2.7 16:31.78 transmission 897 root 20 0 60156 18m 8996 S 9 1.8 11:46.27 Xorg 8340 pm 20 0 38864 15m 10m S 3 1.6 0:37.70 gnome-terminal 1850 pm 20 0 84124 25m 15m S 3 2.6 1:41.56 gnome-panel 8237 pm 20 0 199m 70m 21m S 2 7.1 2:10.27 firefox 1855 pm 20 0 21136 10m 8544 S 1 1.1 0:14.10 gtk-window-deco 1849 pm 20 0 80700 26m 7740 S 1 2.6 1:56.40 compiz.real 1750 pm 20 0 15652 5108 4012 S 1 0.5 2:16.38 at-spi-registry 8623 pm 20 0 2472 1192 884 R 1 0.1 0:00.28 top 1872 pm 20 0 33120 13m 10m S 1 1.4 0:20.61 window-picker-a 50 root 15 -5 0 0 0 S 0 0.0 0:01.89 kondemand/0 1656 ntp 20 0 4228 1188 864 S 0 0.1 0:03.50 ntpd 1751 pm 20 0 98252 10m 7920 S 0 1.0 0:07.24 gnome-settings- 1787 pm 20 0 27224 12m 8668 S 0 1.2 0:13.61 notify-osd 1852 pm 20 0 74292 23m 14m S 0 2.4 0:14.36 netbook-launche 1882 pm 20 0 32044 12m 9388 S 0 1.3 0:07.29 update-notifier 1 root 20 0 2616 1444 1064 S 0 0.1 0:01.42 init 2 root 15 -5 0 0 0 S 0 0.0 0:00.00 kthreadd
Všimněte si procesu s PID 1
. Je to první proces, který je spuštěn při startu systému. Sám dál řídí spouštění dalších. Tvrdí se, že má vždy PID 1, ale není to zcela pravda. Třeba terminálový klient thinstation se chová jinak.
Práce s procesy
Občas se každému stane, že je připojen na konzoli a pustí příkaz, který běží dlouho a konzoli nám tím blokuje. Pokud proces nic nevypisuje (nebo nás výpis nezajímá) můžeme proces pustit na pozadí. Typicky se jedná třeba o mazání nebo kopírování. Pokud rovnou vím, že proces poběží dlouho, stačí na konec příkazu zadat znak &: $ rm -rf /usr/ports &
a dále můžeme v konzoli pracovat. Po dokončení úlohy jsme systémem informováni, jak činnost dopadla:
[1]+ Dokončena rm -rf /usr/ports
Číslo na začátku je identifikátor úlohy (jobu). Úloh na pozadí může být samozřejmě více. Vraťme se ale k našemu problému – spustili jsme mazání a nedali jsme za konec &, takže se proces spustil na popředí. Nevadí, pomocí ctrl + z
úlohu pozastavíme.
[1]+ Pozastavena rm -rf /usr/ports
Kolik úloh a v jakém stavu máme, zjistíme příkazem jobs
.
[root@localhost pm]# jobs [2]+ Pozastavena ftp ftp.xxx.cz [3]- Pozastavena ping 188.120.193.2 > vystup &
A zbývají příkazy fg
(foreground) a bg
(background). Pomocí nich můžeme určit, jak budou procesy dále spuštěny. Zadáme třeba bg 3
. Proces pingu se dále rozběhne na pozadí a jobs ukáže:
[root@localhost pm]# jobs [2]+ Pozastavena ftp ftp.xxx.cz [3]- Běží ping 188.120.193.2 > vystup &
Pomocí fg 2
se můžeme vrátit do procesu s ftp klientem. Ale není problém jej znovu odložit.
Ještě malé zjednodušení – pokud si odložíme jen jeden proces (takže jobs ukazuje pouze jeden, může být zastavený nebo běžící), nemusíme už zadávat číslo jobu, ale stačí jen bg nebo fg.
Pokud máme na pozadí odložené úlohy a zkusíme se odhlásit, systém nás varuje a můžeme procesy korektně ukončit.
Někdy se může stát, že jste u počítače na chvilku a potřebujete spustit nějaký proces na pozadí, který ale poběží dlouho. Buď můžete spustit například program screen
, v něm danou úlohu a pak se od screenu odpojit (tím se zabývá samostatný článek) nebo použít program nohup
. Ten způsobí ignorování signálu SIGHUP, takže se proces neukončí při ukončení shellu.
$ nohup rm -rf /usr/ports &
Mazání rovnou odsuneme na pozadí a můžeme se odhlásit. Nohup nám výstup programu uloží do souboru nohup.out
v aktuálním adresáři. Pokud takový výstupní soubor není možné použít, zkusí ~/nohup.out
.
Změna priority procesu – nice a renice
Další dva programy, které si ukážeme slouží ke změně priority procesu. Když se podíváte na výpis programu top, pátý sloupeček je nice
. To je číslo, které určuje prioritu procesu. Může dosahovat hodnot –20 až 20 (v některých systémech 19). Výchozí hodnotou spuštěných procesů je 0. Např. hodnota +20 ve FreeBSD způsobí, že se daný proces bude vykonávat pouze pokud žádný jiný proces po systému nic nepožaduje. Běžný uživatel může spustit příkaz pomocí nice a nastavit mu jinou prioritu, ale pozor – běžný uživatel může zadávat jen vyšší hodnotu nice a tím nižší prioritu procesu. Pouze uživatel root může zadat i zápornou hodnotu a tím prioritu zvýšit.
nice -n 15 prikaz -parametr
To je sice pěkné, ale co když už program běží s prioritou, která nám nevyhovuje? Pak je tu druhý program – renice
. Zadá se mu nová priorita a PID procesu:
pm@gate ~ $ renice +5 21283 21283: old priority 0, new priority 5
Opět platí, že root může nastavit zápornou hodnotu a tím prioritu zvýšit. Je možné ale zvedat prioritu ne jednomu procesu, ale např. všem procesům jednoho uživatele:
pm@gate ~ $ renice +6 -u pm
Ukončování procesů
Jako někdy zlobí děti své rodiče, i leckterý potomek procesu nebo sám proces zazlobí. V reálném životě ho za to asi nezabijete, ale tady můžete. V textovém režimu se používají nejčastěji příkazy kill
a killall
.
pm@gate ~ $ kill PID
Takto zadaný příkaz pošle procesu signál pro ukončení (TERM). Někdy ani to nestačí a je nutné říct, který signál použít, nejčastěji to bude patrně signál KILL. Lze spustit:
pm@gate ~ $ kill -s KILL PID nebo pm@gate ~ $ kill -9 PID nebo pm@gate ~ $ kill -HUP PID
Některé používané signály
1 | HUP (hang up) |
2 | INT (interrupt) |
3 | QUIT (quit) |
6 | ABRT (abort) |
9 | KILL (non-catchable, non-ignorable kill) |
14 | ALRM (alarm clock) |
15 | TERM (software termination signal) |
Programu kill předáváme PID procesu, pokud ale chceme zabít více procesů (třeba kousnutý prohlížeč firefox) použijeme killall
, stačí zadat:
pm@gate ~ $ killall firefox
Případně můžeme opět doplnit typem signálu. Stejně jako u kill můžete použít název signálu (bez úvodního SIG, takže třeba HUP) nebo číslo signálu.
Ještě pro doplnění uvedu programy pgrep
a pkill
. Dovolují nám o trochu více než killall, mají více parametrů pro výběr procesu (dle uživatele, skupiny, pouze potomky nějakého procesu nebo třeba nejstarší/nejmladší ze skupiny stejných procesů). Rozhodně si pgrep prozkoumejte. Většinou si pomocí pgrep najdete vhodné procesy a pak jen s těmito parametry spustíte pkill.
pm@gate ~ $ pgrep openvpn 89653 12281 4964 77940 56163 41886
Velice pěkné a účinné může být takovéto spojení nice +19 `pgrep bash -u jiny_uzivatel`
.
Ještě zmíním program xkill
. Po spuštění v okenním manažeru se nám změní kurzor a po kliknutí na zlobivé okno bude tento problematický „objekt“ ukončen. Pozor, nezabijte si něco, co nechcete. Já si jednou uklepnutím zabil panel v Gnome a nemohl jej dostat zpět (nepomohl ani restart).
Jistě jsem nezmínil všechny možnosti. Pokud vám nebude souhlasit nějaký parametr, podívejte se do manuálové stránky. Čerpal jsem z FreeBSD a Ubuntu a vše není úplně stejné. Ale většina uváděných příkladů bude fungovat na Linuxu i ostatních unixech, některé uváděné programy nemusí být v systému a bude nutné je doinstalovat, například pstree na FreeBSD:
$ cd /usr/ports/sysutils/pstree $ make install clean