Protsessid ja multitasking
Protsessid ja multitasking
Sisukord
Sissejuhatus
Eelarvamuste kõigutamiseks peab kohe mainima, et multitasking ikka on võimalik. St. et üks arvuti tegeleb korraga mitme tegevusega, kusjuures saab tuua esile ühe või teise või kolmanda .. . Praegu ei tule meelde, aga miski tarkvaratootja kasutab seda sõna vastupidist olukorda märkimaks :) Linuxis on kõik töötavad programmid nummerdatud PID -idega (process identification). Protsessidega seoses on olemas selge seaduspära: iga protsess on nö. mingi teise protsessi poolt sünnitatud (tegelikult võib üks protsess ka teiseks muttuda - nii muutub nt. getty bash -iks). Protsessil võib olla mitu last aga lapsel võib olla ainult üks vanem. Niisiis mitte absoluutne analoogia inimestega. Kui süsteem käivitatakse toimub midagi sellist:
- arvuti leiab kuidagi (nt. LILO abil) bootloader'i vajalikud osad
- loeb üles kerneli (/vmlinuz)
- leiab failisüsteemist üles faili /sbin/init - kõikide protsesside ema (init-i PID = 1 ja PPID=0)
- edasi loetakse läbi /etc/rc.d/.. scriptid (rc - run command) ja käivitatakse palju süsteemi kui terviku seisukohalt olulisi programme
- lõpuks ilmub ekraanile login prompt (st. käivitatakse getty - get tty)
- kui getty'i saab username ja parooli siis ta käivitab bash shelli (tegelikult getty asendab ennast bash'iga) - kasutaja login shelli.
- sealt edasi on teie valik millised protsesse edasi teha
Illustreeriv skeem loginud kasutajatest
Protsesside puud näeb ka käsuga pstree
# pstree init-+-2*[agetty] |-apache2-+-13*[apache2] | |-logger | |-ruby18---ruby18 | `-15*[{apache2}] |-cron |-dhcpd |-in.tftpd |-master-+-pickup | `-qmgr |-munin-node |-ntpd |-openvpn |-portmap |-rpc.idmapd |-rpc.mountd |-sshd---sshd---sshd---bash---su---bash---pstree |-syslog-ng `-udevd
Protsessidega on selline tore lugu et neid saab peatada (st. ära tappa, kill, terminate) ja katkestada (suspend, stop). Peatamise ja katkestamise vahe seisneb selles, et peatatud protsessiga on kõik lõppenud aga katkestatud protsessi saab jätkama panna sellest kohast kus ta tegevus peatati. Ja veel oluline asi - igal protsessil on omanik. Olulistel protsessidel on omanikuks root. Reegel on selline, et peatada ja ära tappa saab vaid endale kuuluvaid protsesse.
Süsteem 'laura' protsessid
Vaatame ühte tabelit kus on kirjas kõik süsteemis laura.oolberg.co (192.168.1.2) töötavad protsessid koos asjajuurde kuuluvate andmetega (ethernetis on kaks linuxi arvutit suvi (192.168.1.3) ja laura):
peale laura bootimist:
- logis tema klaviatuurilt sisse tty2-alt 'kruu' ja andis käsk 'talk root@suvi.oolberg.co' ; suve root vastas talle talk kruu@laura
- logis tema klaviatuurilt sisse tty3 -alt 'triin' ja andis käsu 'mc'
- suvest tegi root telnet'i laurasse ja login end sisse imre alt ja tegi 'ps fjax > psfjax' mis on all toodud
- suvest tegi root veel 'ftp laura' ja logis imre alt sisse (suvel jookseb X)
laura protsessid:
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0 1 0 0 ? -1 S 0 0:02 init [3] 1 2 1 1 ? -1 SW 0 0:00 (kflushd) 1 3 1 1 ? -1 SW< 0 0:00 (kswapd) 1 4 1 1 ? -1 SW 0 0:00 (nfsiod) 1 5 1 1 ? -1 SW 0 0:00 (nfsiod) 1 6 1 1 ? -1 SW 0 0:00 (nfsiod) 1 7 1 1 ? -1 SW 0 0:00 (nfsiod) 1 13 13 13 ? -1 S 0 0:00 /sbin/update 1 63 40 40 ? -1 S 0 0:00 /usr/sbin/rpc.mountd 1 67 40 40 ? -1 S 0 0:00 /usr/sbin/crond -l10 1 54 54 54 ? -1 S 0 0:00 /usr/sbin/syslogd 1 57 57 57 ? -1 S 0 0:00 /usr/sbin/klogd 1 59 59 59 ? -1 S 1 0:00 /usr/sbin/rpc.portmap 1 61 61 61 ? -1 S 0 0:00 /usr/sbin/inetd 61 92 61 61 ? -1 S 0 0:00 \_ in.telnetd 92 93 93 93 p0 155 S 1002 0:00 | \_ -bash 93 155 155 93 p0 155 R 1002 0:00 | \_ ps axfj 61 145 61 61 ? -1 S 1002 0:00 \_ ftpd: suvi.oolberg.co:imre: IDLE 1 65 65 65 ? -1 S 0 0:00 /usr/sbin/rpc.nfsd 1 75 75 75 ? -1 S 0 0:00 /usr/sbin/httpd 75 76 75 75 ? -1 S 65534 0:00 \_ /usr/sbin/httpd 75 77 75 75 ? -1 S 65534 0:00 \_ /usr/sbin/httpd 75 78 75 75 ? -1 S 65534 0:00 \_ /usr/sbin/httpd 75 79 75 75 ? -1 S 65534 0:00 \_ /usr/sbin/httpd 75 80 75 75 ? -1 S 65534 0:00 \_ /usr/sbin/httpd 75 118 75 75 ? -1 S 65534 0:00 \_ /usr/sbin/httpd 75 119 75 75 ? -1 S 65534 0:00 \_ /usr/sbin/httpd 1 81 81 81 ? -1 S 0 0:00 /usr/sbin/smbd -D 1 83 83 83 ? -1 S 0 0:00 /usr/sbin/nmbd -D 1 85 85 85 ? -1 S 0 0:00 gpm -R -m /dev/mouse -t ms 1 86 86 86 1 86 S 0 0:00 /sbin/agetty 38400 tty1 linux 1 87 87 87 2 128 S 1000 0:00 -bash 87 128 128 87 2 128 S 1000 0:00 \_ talk root@suvi 1 88 88 88 3 136 S 1003 0:00 -bash 88 136 136 88 3 136 S 1003 0:00 \_ mc 136 137 137 137 ? -1 S 0 0:00 \_ cons.saver /dev/tty3 136 138 138 138 p1 138 S 1003 0:00 \_ bash -rcfile .bashrc 1 89 89 89 4 89 S 0 0:00 /sbin/agetty 38400 tty4 linux 1 90 90 90 5 90 S 0 0:00 /sbin/agetty 38400 tty5 linux 1 91 91 91 6 91 S 0 0:00 /sbin/agetty 38400 tty6 linux
Siit tabelist saab teha hulka järledusi, kommenteerime rasvaseid ridu järjekorras:
- init'i PID (process identification) on 1 ja PPID (prosess parent identification) on 0 - inetd on daemon mis sünnitab vajadusel ftp ja telnet'i kutsele vastuseid - httpd -dest on üks teiste httpd'de ema (vt. PID ja PPID numbreid) ja nad on daemonid mis teenidavad netscapega tulnud külalisi - gpm on hiirega tegelev programm - tty1, 4, 5 ja 6 getty'd ootavad aga tty2 ja tty3 on getty muutunud bash-iks ja sünnitanud uusi protsesse. - STAT tulba S tähendab started - ja TTY tulba ? tähendab, et protsessiga pole ühtki terminali seotud
Kopeerisin siia alla ka veel ühe laural antud käsu output'i (olen ju sinna imre'na sisse loginud)
laura:~$ ps axfju USER PID %CPU %MEM SIZE RSS TTY STAT START TIME COMMAND bin 59 0.0 1.3 824 312 ? S 12:26 0:00 /usr/sbin/rpc.portmap kruu 87 0.0 2.6 1128 608 2 S 12:26 0:00 -bash kruu 128 0.0 2.6 1116 608 2 S 12:32 0:00 \_ talk root@suvi root 1 0.1 1.5 828 356 ? S 12:26 0:02 init [3] root 2 0.0 0.0 0 0 ? SW 12:26 0:00 (kflushd) root 3 0.0 0.0 0 0 ? SW< 12:26 0:00 (kswapd) root 4 0.0 0.0 0 0 ? SW 12:26 0:00 (nfsiod) root 5 0.0 0.0 0 0 ? SW 12:26 0:00 (nfsiod) root 6 0.0 0.0 0 0 ? SW 12:26 0:00 (nfsiod) root 7 0.0 0.0 0 0 ? SW 12:26 0:00 (nfsiod) root 13 0.0 1.1 800 260 ? S 12:26 0:00 /sbin/update root 54 0.0 1.8 836 412 ? S 12:26 0:00 /usr/sbin/syslogd root 57 0.0 2.2 1016 520 ? S 12:26 0:00 /usr/sbin/klogd root 61 0.0 1.4 824 336 ? S 12:26 0:00 /usr/sbin/inetd imre 166 0.1 3.0 936 696 ? S 13:05 0:00 \_ ftpd: suvi.oolberg.co: imre:IDLE root 92 0.0 2.2 1108 504 ? S 12:26 0:00 \_ in.telnetd imre 93 0.0 2.6 1128 608 p0 S 12:26 0:00 \_ -bash imre 169 0.0 1.8 892 416 p0 R 13:06 0:00 \_ ps axfju root 63 0.0 1.8 872 412 ? S 12:26 0:00 /usr/sbin/rpc.mountd root 65 0.0 1.8 892 420 ? S 12:26 0:00 /usr/sbin/rpc.nfsd root 67 0.0 1.4 824 340 ? S 12:26 0:00 /usr/sbin/crond -l10 root 75 0.0 2.5 1056 584 ? S 12:26 0:00 /usr/sbin/httpd nobody 76 0.0 2.8 1080 656 ? S 12:26 0:00 \_ /usr/sbin/httpd nobody 77 0.0 2.8 1080 648 ? S 12:26 0:00 \_ /usr/sbin/httpd nobody 78 0.0 2.5 1056 584 ? S 12:26 0:00 \_ /usr/sbin/httpd nobody 79 0.0 2.5 1056 584 ? S 12:26 0:00 \_ /usr/sbin/httpd nobody 80 0.0 2.5 1056 584 ? S 12:26 0:00 \_ /usr/sbin/httpd nobody 118 0.0 2.5 1056 584 ? S 12:30 0:00 \_ /usr/sbin/httpd nobody 119 0.0 2.5 1056 584 ? S 12:30 0:00 \_ /usr/sbin/httpd root 81 0.0 2.6 1248 616 ? S 12:26 0:00 /usr/sbin/smbd -D root 83 0.0 2.7 1096 620 ? S 12:26 0:00 /usr/sbin/nmbd -D root 85 0.0 1.4 832 324 ? S 12:26 0:00 gpm -R -m /dev/mouse -t ms root 86 0.0 1.2 816 292 1 S 12:26 0:00 /sbin/agetty 38400 tty1 linux root 89 0.0 1.2 816 292 4 S 12:26 0:00 /sbin/agetty 38400 tty4 linux root 90 0.0 1.2 816 292 5 S 12:26 0:00 /sbin/agetty 38400 tty5 linux root 91 0.0 1.2 816 292 6 S 12:26 0:00 /sbin/agetty 38400 tty6 linux triin 88 0.0 2.6 1124 604 3 S 12:26 0:00 -bash triin 136 0.0 3.8 1700 876 3 S 12:34 0:00 \_ mc root 137 0.0 1.1 812 264 ? S 12:34 0:00 \_ cons.saver /dev/tty3 triin 138 0.0 2.6 1132 600 p1 S 12:34 0:00 \_ bash -rcfile .bashrc laura:~$
Siit on näha ka protsesside omanikud aga pole näha PPID numbreid. Ma kahjuks ei osanud anda ps 'le sellised võtmeid, et näha omanikke, PID ja PPID numbreid korraga :(
Siiamaani kõneldud jutu mõte oli anda aimu ja vahendeid (man ps) mis süsteem on ja kuidas olukorda jälgida. Jah, veel on abiks programm top - seda pole aga mõtet lihtsalt taustaks käima jätta, pidi masinat suhteliselt palju koormama.
Protsessile signaali saatmine
See on viisakalt öeldud. Tihti on vaja saata kaht moodi signaale:
- tappa ära: kill <PID> nt. mc tapmiseks kill 136. kui ei sure siis saata kill -INT 136 või isegi kill -TERM 136 - lasta protsessile vastaval programmil uuesti läbi lugeda .conf failid: nt. killall -HUP httpd web'i serveri jaoks
Tapmislusti vähendamiseks peab tunnistama, et protsesse (programme) on loomulik lõpetada programmi sisemisi vahendeid kasutades: nt. mc puhul F10. Muidu võivad protsessid zombideks muutuda ja see on halb.
Jobs
Kui üks kasutaja on end masinasse vaid üks kord sisse loginud ja õiendab oma shellis, siis shell võimaldab sellist asja nagu job control (tegelikult on igal bash shellil oma jobid - st. kui on kaks xterminali lahti, siis kummagil on oma jobs list kuigi protsessid käivad ikka samal protsessoril külas :). Arvutid töötavad nii kiiresti ja inimesed nii rahulikult, et ega korraga polegi tavaliselt vaja mitut programmi tööle panna aga vahel siiski. Programmid võivad nö. käia kahes olekus:
ees - foregroundis (siis oleme proptist ilma!) taga - backgroundis (prompt jääb alles aga programm töötab).
Samuti saab juba kuskil töötavaid programme viia backgroundi või tuua foregroundi.
Tavaliselt käivitatakse programm trükkides tema nimi käsureale ja vajutades reavahetust. Nii läheb ta tööle foregroundis. Nii töötavat programmi saab:
- peatada Ctrl + C -ga (see on sisuliselt kill -INT <PID> saatmine) - katkestada (kusjuures jääb võimalus teada panna jätkama poolelijäänud kohast käsuga fg) Ctrl+ Z -ga
Näited:
yes
käivitame programmi yes mis hakkab trükkima y tähti standard output'i.
bash # yes y y y .... Ctl + C
ja proovige ka
bash # yes y y y .. Ctl + Z [1]+ Stopped yes bash #
ja
andes käsu jobs näete mis tööd parasjagu kuidas on:
bash #jobs [1]+ Stopped yes bash #
ja kui tahate ta taas tööle panna siis kasuga fg
bash # fg y y y ..
Lõpuks tapke ära Ctrl +C
See on muidugi loll näide :(
aastad, kuud, nadalad
kui meil on olemas näiteks kolm programmi nadalab, kuud ja aastad mis ei tee tegelikult midagi aga ekraani ka ei puutu siis saame nad korraga tööle panna selliselt:
bash# aastad &; kuud &; nadalad &
kõige lihtsam:
#include<stdio.h> { while (1); return 0; }
see on mul ära kompilleeritud ja kopeeritud nende kolme nime alla kataloog /bin :)
ning andes käsu
bash # jobs
näeme midagi sellist:
[1] Running aastad [2]- Running kuud [3]+ Running nadalad
kui soovime mingil põhjusel tuua neist mõne esiplaanile, siis anname käsu
fg %jobnumber nt. bash # fg %2
kui tahame ta nüüd korraks katkestada siis vajutame Ctrl + Z
(vaadake jobs kasuga mis sai)
kui aga taas jätkata
fg %jobnumber või bg %jobnumber
kui aga tahame mõne ära lõpetada
kill %jobnumber
NB! toodud käske ei saa muidu anda kui prompt pole vaba. Nii et peate vajadusel saatma kõik background'i. Õigluse huvides olgu üteldud, et programm top näitab hästi ära ja update'b ps -i. Proovige!
Ei väsi rõhutamast, kui olla kahest kohast ühte masinasse sisse loginud, siis on jobid eraldi nummerdatud kuivord käivad kaks shelli ja job control on shelli feature. Veelgi: fg, bg on shelli nö. sisemised käsud.
Protsessi exit code
Osutub, et UNIX-is programmid ehk protsessid mitte ei lõpeta oma tööd ja kõik vaid tagastavad neid väljakutsunud keskonnale arvu näitamaks kuidas protsess lõppes. Tõsisele programmeerijale on oluline teada enamat kui siin järgnevast aga shell script'tide kirjutamiseks esialgu piisab ka sellest.
Teeme lihtsad katsed:
bash # ls mina sina tema bash # echo $? 0
bash # kaskmidakindlastieiole bash: kaskmidakindlastieiole: command not found echo $? 127
bash # ls | grep mina echo $? 0
bash # ls | grep mina echo $? 1
niisiis, keskkonnamuutuja $? omandab viimasena lõpetanud protsessi exit code'i väärtuse, mis on üldiselt 0 kui asi õnnestus ja mittenull kui ebaõnnestus. Siin on paha see, et C keeles loetakse õnnestumiseks 1 ja 0 mitteõnnestumiseks (tõene ja mittetõene loogilise tehte tulemus) . Aga mis teha, traditsioonid, traditsioonid ...
Lingid
http://www.marcelgagne.com/cwl122002.html protsessidest ja mõned huvitavad ideed nende visualiseeritud vaatamisest