next up previous contents
Nästa: 6. Skalet Bash Upp: 5. Hur gör man? Förra: 5.4 Att arkivera filer

   
5.5 Processkontroll

I avsnitt 3.2 beskrev vi det gränssnitt till jobbkontroll som Bash erbjuder. I detta avsnitt ska vi ta upp fler sätt att kontrollera och manipulera processer.

Med hjälp av kommandot ps kan man kontrollera vilka processer som är igång på datorn.$ ps
  PID TTY STAT TIME COMMAND
 5596  p0 S    0:00 -bash 
 5599  p2 S    0:01 /usr/bin/xdvi.bin -name xdvi gnulinux.dvi
 5639  p2 S    0:00 gs -sDEVICE=x11 -dNOPAUSE -dSAFER -q - 
 5668  p0 R    0:00 ps 
$
Status för en process (rubriken STAT ovan) kan vara R (Running; igång), S (Sleeping; sysslolös) och T (Stopped; stoppad, eller snarare pausad). Instruktionen som startade respektive process anges i sista fältet av varje rad ovan. Det näst sista fältet visar hur mycket av datorns tid instruktionen tagit i anspråk.

Varje process har ett nummer, dess processidentifikationsnummer (PID), med vars hjälp man referar till processen. De flesta processer har en kontrollterminal, nämligen den terminal processen startades från. Eventuell indata till kommandot läses in från kontrollterminalen, och utdata skrivs ut där. Det andra fältet (under rubriken TTY) ovan anger processens kontrollterminal.

Varje terminal motsvaras av en fil i katalogen /dev. De virtuella terminalerna, som man kommer till genom samtidigt att trycka Ctrl, Alt och en av funktionstangenterna F1 till F6, har filnamn tty1 till tty6, medan pseudoterminaler har filnamn ttyp1, ttyp2 osv. Kommandot ps från sista raden ovan körs i pseudoterminalen /dev/ttyp0.

Flaggorna till ps anges på ett något annorlunda sätt än vanligt (detta kommer att ändras i en kommande utgåva av programmet). Om man ger flaggan u, så skrivs utförligare information ut.$ ps u
USER    PID %CPU %MEM  SIZE   RSS TTY STAT START  TIME COMMAND
göran  5596  0.0  1.9  1832  1228  p0 S    08:32  0:00 -bash 
göran  5599  0.0  3.4  3160  2184  p2 S    08:33  0:01 /usr/bin/xdvi.bi
göran  5639  0.0  3.9  4540  2528  p2 S    10:07  0:00 gs -sDEVICE=x11 
göran  5670  0.0  0.8   908   540  p0 R    10:39  0:00 ps u 
$
Här ser vi också vem som startade processen (USER), när den startades (START), hur många procent av datorns tid (%CPU) respektive minne (%MEM) processen förbrukar, hur stor processen är (SIZE, i kilobyte) samt hur mycket av den som finns i minnet just nu (RSS). Bara de processer man själv startat listas ovan. Använd flaggan a om också alla andras processer ska tas med. De processer som inte har någon kontrollterminal finns inte heller med ovan, utan man måste ge ps flaggan x för att få information om dem.$ ps x
  PID TTY STAT TIME COMMAND
 5580  ?  S    0:01 /usr/X11R6/bin/fvwm2 
 5592  ?  S    0:00 /usr/X11R6/lib/X11/fvwm2/FvwmPager 9
 5594  ?  S    0:00 /usr/X11R6/lib/X11/fvwm2/FvwmButtons
 5595  ?  S    0:00 xclock -update 1 -padding 4 -bg Dark
 5596  p0 S    0:00 -bash 
 5598  ?  S    0:58 /usr/bin/xemacs 
 5599  p2 S    0:01 /usr/bin/xdvi.bin -name xdvi gnulinu
 5639  p2 S    0:00 gs -sDEVICE=x11 -dNOPAUSE -dSAFER -q
 5672  p0 R    0:00 ps x
$
De processer som saknar kontrollterminal har ett frågetecken under rubriken TTY. I utskriften ovan finns fem sådana processer; de utgörs av fönsterhanteraren och program som startats genom den.

Kommandot top ger ungefär samma information som ps. Men top sorterar processerna efter hur mycket processortid de använder, och informationen uppdateras med jämna intervall tills man trycker q. Man skulle kunna säga att top är en ''live-version'' av ps. Det finns åtskilliga X-program som ger motsvarande information, tex Gtop, se figur 5.1.

Här är ett exempel på utdata från programmet top:

 10:53am  up 16 days, 22:07,  3 users,  load average: 0.00, 0.00, 0.10
41 processes: 40 sleeping, 1 running, 0 zombie, 0 stopped
CPU states:  3.7% user,  0.9% system,  0.0% nice, 95.4% idle
Mem:   63356K av,  61184K used,   2172K free,  26664K shrd,   9376K buff
Swap:  96352K av,    316K used,  96036K free                 23856K cached

  PID USER     PRI  NI  SIZE  RSS SHARE STAT  LIB %CPU %MEM   TIME COMMAND
5675 göran     19   0   772  772   592 R       0  3.7  1.2   0:00 top
15350 root       8   0  5268 5260  1596 S       0  0.9  8.3  61:42 XF86_Mach64
    1 root       0   0   232  216   160 S       0  0.0  0.3   0:01 init
    2 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 kflushd
    3 root     -12 -12     0    0     0 SW<     0  0.0  0.0   0:00 kswapd
    4 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 nfsiod
    5 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 nfsiod
    6 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 nfsiod
    7 root       0   0     0    0     0 SW      0  0.0  0.0   0:00 nfsiod
15326 root       0   0   972  972   656 S       0  0.0  1.5   0:00 bash
15324 root       0   0   312  312   232 S       0  0.0  0.4   0:00 getty
  119 root       0   0   580  548   452 S       0  0.0  0.8   0:05 sshd
   14 root       0   0    92   64    52 S       0  0.0  0.1   0:07 update
   85 root       0   0   372  364   272 S       0  0.0  0.5   0:00 syslogd
   87 root       0   0   360  352   180 S       0  0.0  0.5   0:00 klogd
   96 root       0   0   204  196   148 S       0  0.0  0.3   0:00 kerneld
  100 daemon     0   0   344  340   268 S       0  0.0  0.5   0:00 portmap
  102 root       0   0   376  368   300 S       0  0.0  0.5   0:00 inetd
  152 root       0   0   304  284   224 S       0  0.0  0.4   0:00 getty
  126 root       0   0   760  748   356 S       0  0.0  1.1  22:00 rpc.nfsd
  128 root       0   0   568  556   444 S       0  0.0  0.8   0:00 rpc.mountd
  132 nobody     0   0   272  264   204 S       0  0.0  0.4   0:00 dhttpd
  135 daemon     0   0   308  276   220 S       0  0.0  0.4   0:00 atd
  138 root       0   0   348  340   256 S       0  0.0  0.5   0:00 cron
30196 root       0   0  1544 1544  1204 S       0  0.0  2.4   0:00 xdm
  153 root       0   0   296  296   216 S       0  0.0  0.4   0:00 getty
15348 root       0   0   684  672   572 S       0  0.0  1.0   0:00 xdm
 5580 göran      1   0  1284 1284   896 S       0  0.0  2.0   0:01 fvwm2
 5590 root       0   0  2104 2104  1448 S       0  0.0  3.3   0:01 xterm
30205 root       0   0  1436 1436  1196 S       0  0.0  2.2   0:00 xconsole.real
 5592 göran      0   0   720  720   620 S       0  0.0  1.1   0:00 FvwmPager
 5595 göran      0   0  1260 1260  1052 S       0  0.0  1.9   0:00 xclock
 5594 göran      0   0   808  808   696 S       0  0.0  1.2   0:00 FvwmButtons
 5596 göran     15   0  1228 1228   884 S       0  0.0  1.9   0:00 bash
30150 root       0   0  1456 1436   700 S       0  0.0  2.2   2:29 sshd
 5599 göran      0   0  2184 2184  1328 S       0  0.0  3.4   0:01 xdvi.bin.real
 5598 göran      0   0  7464 7464  3056 S       0  0.0 11.7   1:01 xemacs
 5639 göran      0   0  2528 2528  1736 S       0  0.0  3.9   0:00 gs
30152 eva        0   0  1176 1176   860 S       0  0.0  1.8   0:00 bash
30154 eva        0   0  9544 9540  1876 S       0  0.0 15.0   0:48 gimp
30155 eva        0   0  1996 1980   708 S       0  0.0  3.1   0:00 script-fu

  gtop.gif

Man kan ''kommunicera'' med en process genom att skicka signaler till den med hjälp av kommandot kill. Ofta används kill till att avsluta processer, men kommandot kan också ha andra, mindre destruktiva effekter - tex att processen tar en paus eller att den startar om. Bara root och ägaren av en process får skicka signaler till den.

Signaler har såväl namn som nummer. Man kan referera till en signal antingen med dess namn, som tex SIGCONT (eller kortare CONT), eller dess nummer, som 18. Några viktiga signaler ges i tabell 5.2.

Processer kan förbereda sig för att ta emot olika signaler, och ha en åtgärd redo ifall en viss signal skulle komma. Man säger då att processen fångar signalen. Åtgärden kan vara att helt enkelt strunta i signalen, eller tex att spara alla data, skriva ett felmeddelande och avsluta. Om signalen inte fångas, så vidtas en standardåtgärd på processen. Två av signalerna, SIGKILL och SIGSTOP, kan aldrig fångas.


 
Tabell: Några signalnamn
 
Signal Nummer Betydelse Standardåtgärd
SIGHUP 1 Avringd avsluta
SIGINT 2 Avbruten avsluta
SIGSTOP 19 Stoppad stanna
SIGCONT 18 Återupptagen  
SIGKILL 9 Dödad avsluta
SIGTERM 15 Avslutad avsluta
SIGSEGV 11 Segmenteringsfel avsluta

Vi minns att man kan pausa ett förgrundsjobb i Bash genom att trycka C-z. Mer allmänt kan man pausa en process genom att skicka signalen SIGSTOP till den. För att låta processen fortsätta kan man vid ett senare tillfälle skicka signalen SIGCONT till den.$ gzip -9 /tmp/gnulinux.ps &
[1] 5682
$ ps 5682
  PID TTY STAT TIME COMMAND
 5682  p0 R    0:04 gzip -9 /tmp/gnulinux.ps
$ kill -STOP 5682
$ ps 5682
  PID TTY STAT TIME COMMAND
 5682  p0 T    0:14 gzip -9 /tmp/gnulinux.ps

[1]+  Stopped                 gzip -9 /tmp/gnulinux.ps
$ kill -CONT 5682
$ ps 5682
  PID TTY STAT TIME COMMAND
 5682  p0 R    0:21 gzip -9 /tmp/gnulinux.ps
$ ls /tmp
gnulinux.ps.gz
[1]+  Done                    gzip -9 /tmp/gnulinux.ps
$
Ovan körs först en tung process igång. Med hjälp av ps ser vi att processen kör för fullt. Kommandot kill -STOP 5682 skickar signalen SIGSTOP till processen, och en kontroll visar att den faktiskt är pausad (dess status är T). Efter en stund skickas signalen SIGCONT till processen, och då fortsätter den därifrån den stannade. Dess status är återigen R. Senare, efter kommandot ls /tmp, ser vi att processen kört färdigt.

Kommandot kill vill som flagga ha namn eller nummer på en signal att skicka. Om flaggan utelämnas, så skickas signalen SIGTERM. Argumenten består av ett eller flera processidentifikationsnummer, som anger vilken eller vilka processer signalen ska skickas till. Om kill anropas med flaggan -l, så ges en lista över alla signaler.$ kill -l
 1) SIGHUP      2) SIGINT      3) SIGQUIT     4) SIGILL
 5) SIGTRAP     6) SIGABRT     7) SIGBUS      8) SIGFPE
 9) SIGKILL    10) SIGUSR1    11) SIGSEGV    12) SIGUSR2
13) SIGPIPE    14) SIGALRM    15) SIGTERM    17) SIGCHLD
18) SIGCONT    19) SIGSTOP    20) SIGTSTP    21) SIGTTIN
22) SIGTTOU    23) SIGURG     24) SIGXCPU    25) SIGXFSZ
26) SIGVTALRM  27) SIGPROF    28) SIGWINCH   29) SIGIO
30) SIGPWR
$

Signalen SIGTERM är en önskan om att processen ska avsluta. Vissa processer fångar denna signal och struntar i den. Andra processer fångar signalen, sparar sina data och städar upp efter sig innan de avslutar. Slutligen finns det processer som inte fångar signalen SIGTERM, och då vidtas standardåtgärden som är att avsluta dem. Om man vill ta bort en process som inte ger med sig på något annat sätt, så kan man skicka SIGKILL till den. Då avslutas processen utan att den först ''tillfrågas''. Detta kan ha obehagliga effekter - om man tex skickar SIGKILL till Emacs, så förlorar man alla ändringar som inte är sparade. Det är alltså bäst att prova SIGTERM först; bara om detta inte hjälper ska man använda SIGKILL.

Antag att vi har följande processer igång:$ ps
  PID TTY STAT   TIME COMMAND
 1485  p1 S      0:00 -bash
 1491  p2 S      0:00 -bash
 1502  p3 S      0:00 xdvi.bin -name xdvi oh.dvi
 1549  p2 R     54:05 dedekind 1232112423
 1598  p1 R      0:00 ps
$
Vi försöker nu ta bort process 1491, ett Bash-skal:$ kill 1491
$ ps 1491
  PID TTY STAT   TIME COMMAND
 1491  p2 S      0:00 -bash
$
Kontrollen med ps visar att Bash-skalet finns kvar. Detta beror på att Bash fångar signalen SIGTERM och struntar i den. Vi måste då ta till SIGKILL:$ kill -9 1491
$ ps 1491
  PID TTY STAT   TIME COMMAND
No processes available.
$
Utskriften från ps visar att processen är borttagen. Process 1549 (som körde under det skal vi nyss tog bort och som nu saknar kontrollterminal) kan vi däremot ta bort med SIGTERM:$ ps 1549
  PID TTY STAT   TIME COMMAND
 1549  ?  R     62:33 dedekind 1232112423
$ kill 1549
$ ps 1549
  PID TTY STAT   TIME COMMAND
No processes available.
$

När man i skalet trycker C-c skickas signalen SIGINT till de processer som är i förgrunden. Detta får vanligtvis processerna att avsluta.

Signalen SIGHUP betyder att processen är ''avringd'', vilket tex kan innebära att man loggat ut. Vissa processer struntar i denna signal, andra avlutar och åter andra läser in sina konfigurationsfiler och startar om. Om man vill att en process ska ligga kvar även efter att man loggat ut, så måste man i vissa fall skydda den mot signalen SIGHUP. Detta gör man genom att starta den med nohup kommando &

Om ett program ''utför en förbjuden åtgärd'', så skickas signalen SIGSEGV till den. Nästan alltid får detta till följd att programmet avslutar och gör en minnesutskrift i en fil med namnet core. Minnesutskriften är till för att programutvecklare ska kunna ta reda på vad som vållade felet.

Kommandot killall är en variant av kill. Skillnaden mellan dessa kommandon ligger i hur man anger vilka processer signalen ska skickas till. I fallet kill anges processernas PID, men till killall anges i stället det kommando som startade processerna. En fördel med killall är att vi slipper ta reda på PID för processerna ifråga.$ xfontsel &
[1] 5874
$ killall xfontsel
[1]+  Avslutad                xfontsel
$

Om en process startar en ny process, så är den nya processen barn till den gamla, och den gamla processen är förälder till den nya. Förälderns PID kallas för processens PPID. Kommandot pstree ritar ut processernas släktträd med utgångspunkt från urmodern init (som har PID 1) eller, om man vill, från en given process.$ ps x
  PID TTY STAT TIME COMMAND
 5580  ?  S    0:04 /usr/X11R6/bin/fvwm2 
 5592  ?  S    0:00 /usr/X11R6/lib/X11/fvwm2/FvwmPager 9
 5594  ?  S    0:00 /usr/X11R6/lib/X11/fvwm2/FvwmButtons
 5596  p0 S    0:00 -bash 
 5598  ?  S    1:48 /usr/bin/xemacs 
 5599  p2 S    0:02 /usr/bin/xdvi.bin -name xdvi gnulinu
 5639  p2 S    0:00 gs -sDEVICE=x11 -dNOPAUSE -dSAFER -q
 5868  ?  S    0:00 xclock -update 1 -padding 4 -bg Dark
 5876  p0 R    0:00 ps x
$ pstree 5580
fvwm2-+-FvwmButtons
      |-FvwmPager
      |-xclock
      `-xterm---bash---pstree
$

Varje process har ett snällhetsvärde som bestämmer hur stor del av processorns tid processen får. Värdet är ett heltal mellan -20 och 19. Ju högre värdet är, desto snällare är processen i den meningen att den kräver mindre av processorkraften. Vanligtvis ärver en process snällhetsvärdet från sin förälder; standardvärdet är 0. Det är bara root som får sänka snällhetsvärdet för en process. Däremot kan vanliga användare höja det för sina processer med kommandot nice. Om en process startas med nice kommando, så ges den ett snällhetsvärde som är 10 enheter större än dess förälder (men högst 19). Om den ska ha tex värdet 5 högre än föräldern, ska den startas med instruktionen nice -n 5 kommando. Om man ger denna instruktion i ett skal med snällhetsvärde 10, så körs alltså kommando med snällhetsvärde 15. Snällhetsvärdet skrivs ut under rubriken ''NI'' i top, se tabell 5.1.

Om en process redan är igång, så kan man ändra dess snällhetsvärde med kommandot renice. Nedan startar vi en process och sätter sedan dess snällhetsvärde till 3.$ xfontsel &
[1] 5935
$ renice +3 5935
5935: old priority 0, new priority 3
$
Vi ändrar snällhetsvärdet till 7:$ renice +7 5935
5935: old priority 3, new priority 7
$
Man får inte sänka värdet, utan bara höja det.$ renice +5 5935
renice: 5935: setpriority: Åtkomst nekas
$


next up previous contents
Nästa: 6. Skalet Bash Upp: 5. Hur gör man? Förra: 5.4 Att arkivera filer
Goran Andersson
1999-03-08