Boken Om Linux/Kapittel 11

Fra Wikibøker – frie læremidler

11: Linux-prosesser[rediger]

Foreldre- og barneprosesser[rediger]

En prosess er et program som utføres. En prosess kan starte opp nye prosesser. Originalprosessen kaller man opphavet (foreldre), og den nye prosessen kalles barn. Når et program er utført, stopper tilhørende prosess. En foreldreprosess kan avsluttes før barnet. Barnet får da prosess 1 (/sbin/init under Linux og /etc/init under standard Unix V.4) som opphavsprosess.

Alle prosesser har et unikt prosessnummer som vanligvis kalles PID. PID-nummeret. For Linux-kjerner høyere enn 2.6 (# uname -a) kan PID-nummeret være mellom 0 og 4000000000. Har du en Linux-kjerne basert 2.4 kan PID-nummeret være mellom 0 og 65565.

Alle Linux-systemer har en grense for hvor mange prosesser som kan være aktive på systemet, og hvor mange prosesser en bruker kan ha. Disse grensene settes i Linux-kjernen.

Har du en Linux-kjerne som er lavere enn 2.5.34, er Linux-systemet ditt begrenset til totalt 32768-prosesser. I Linux-kjerner høyere eller lik 2,4, er totalt antall prosesser begrenset av systemets minne, som kan være maksimalt 512 GB (Intel socket 2011-3 Xeon dual cpu QPI).

Har du en Linux 4.5 kjerne er Linux-systemet ditt begrenset til totalt 4 billioner prosesser. I praksis er det systemets minne, som vil begrense det totale antall prosesser du kan kjøre.

Eieren av de forskjellige prosessene kan avslutte en prosess med Linux-kommandoen kill. Systemadministrator kan fjerne alle prosesser. Det er Linux-skallet som leser de kommandoene som tastes inn og utfører dem. Skallet setter i gang utførelsen, sender argumentene videre og venter til de er ferdig, før den gir deg en ny ledetekst (klarmelding).

Her skal jeg se på utførelsen av en enkel kommando som echo:

[david@nittedal david]$ echo "Hei"

Hei

Skallet (bash) leser linjen echo "Hei" og skiller ut kommandoen echo fra argumentet. Deretter skjer følgende:

   * Prosessen deler seg i to eksakte kopier.
   * Foreldreprosessen venter på at barnet skal avsluttes.
   * Barnet bytter ut det gamle programmet (bash) med den nye (kommandoen echo "Hei").
   * Barnet utfører programmet.
   * Barnet avsluttes.
   * Foreldreprosessen fortsetter, og du får ledeteksten tilbake. 

Prosessen deler seg i to eksakte kopier. For at en prosess skal kunne lage en kopi av seg selv, må funksjonskallet fork startes. Etter en fork har jeg to prosesser: en barneprosess og en foreldreprosess. Forskjellen mellom de to prosessene er at de har forskjellig PID-nummer. De to prosessene deler åpne filer, og hver prosess vet at den ene er foreldre eller barn til den andre. I vårt eksempel sier opphavet at det ønsker å vente på at barnet blir ferdig; derfor sender det funksjonskallet wait. Barnet bestemmer dermed den videre handlingen; det ønsker å utføre et nytt program og sender funksjonskallet execute. (Ved hjelp av execute kan du transformere prosessen som ble skapt med fork til et nytt program.) Barnet oppgir dermed en liste over nye argumenter til det nye programmet. Linux-kjernen frigjør hukommelse som var tildelt det gamle programmet og laster inn det nye programmet. Det nye programmet (echo) skriver ut sine argumenter på standard utdata (terminalen). Tilslutt utfører echo systemkallet exit og avsluttes. Etter barnets avslutning, våkner det ventende skallet. Foreldreprosessen fortsetter, og du får ledeteksten tilbake.

Forgrunns- og bakgrunns- prosesser[rediger]

Linux er et flerbruker- og flerprosesseringsoperativsystem. Du kan kjøre en prosess i forgrunnen eller i bakgrunnen. Kjører du prosessen i forgrunnen, kommer alle meldinger på skjermen. Du kan derfor bare ha én prosess i forgrunnen.

Du kan kjøre mange bakgrunnsprosesser samtidig. Men husk at alle utdata bør omdirigeres til en fil. Hvis programmet skal gå i forgrunnen, venter skallet på at barneprosessen skal bli ferdig. Programmet som kjøres, kan være en menybasert applikasjon med forventet input fra brukeren eller uten forventet input fra brukeren. Når barneprosessen er ferdig, vil brukeren få Linux-ledeteksten tilbake. Når brukeren setter i gang en prosess som skal gå i bakgrunnen, venter ikke skallet på at barneprosessene skal bli ferdige, men skriver i stedet ut prosessiden til barneprosessen (PID) og gir brukeren ledeteksten tilbake.

Figur 11.1: Eksempel på en forgrunnsprosess

Når du skal starte forgrunnsprosessering, skriver du bare navnet på programmet, og skjerm og tastatur er bundet til programmet.

Figur 11.2: Eksempel på en bakgrunnsprosess

Men hvis du ønsker bakgrunnsprosessering, må du ha med &-tegnet til slutt, etter kommando eller program. Når du har startet en bakgrunnsprosess, får du umiddelbart ledeteksten tilbake, og skallet er klart for nye kommandoer/program. Bakgrunnsprosessen kjøres samtidig med aktivitetene du har i forgrunnen. Den kan ikke kjøres interaktivt.

Eksempel:

[david@nittedal david]$ who > datafil &

Her starter jeg who-kommandoen, resultatet sender jeg til tekstfilen datafil. Siden jeg har tatt med &, kjøres prosessen i bakgrunnen.

Eksempel:

[david@nittedal david]$ linuxprogram &

Her starter jeg programmet linuxprogram, som settes til å kjøre i bakgrunnen.

Eksempler:

[david@nittedal david]$ gcc corelfilter.c &

Her tar jeg en kompilering av C-kildekode i bakgrunnen.

[david@nittedal david]$ who | wc -l > bruker.list &

Resultat av who | wc -l blir sendt til filen bruker.list. Prosessen kjøres i bakgrunnen. Når du starter en prosess i bakgrunnen, får den en egen prosessID (PID) som kommer på skjermen når du har gitt kommandoen.

Prosessoversikt – ps[rediger]

En prosess er vanligvis assosiert med en kommando eller et program. Hver prosess får et unikt prosess-id nummer (PID) ved oppstarten. Prosess-status brukes av driftspersonell for å finne opplysninger om bestemte prosesser eller om alle prosesser i systemet.

Figur 11.3: KDE-programmet kpm med prosess-status

Figuren over viser KDEs prosessovervåkningsprogram (kpm). Her ser du alle prosessene som kjøres.

Enhver prosess har en status som kan endre seg under kjøring. Så lenge prosessen er i gang, vil den ha samme PID-nummer og kjøre fra det samme login-skallet. Eventuelle overflødige prosesser kan fjernes med kill-kommandoen. Med ps-kommandoen ser du hvilke prosesser som er aktive.

Kommandoen ps prosessoversikt
Kommando: ps [a][e][f][l][m][u] ps help
Funksjon: Gir en prosessoroversikt
Argument: Ingen
Opsjoner: Se også Linux-man-sidene.
a Viser alle prosessene (ikke bare dine egne prosesser)
e Her får du også med miljøparametere (environment)
f Viser familietrerelasjoner.
l Viser deg langt format, som inkluderer mer informasjon
t Velg terminal device tty (ps -t5 sjekker tty5)

Eksempel:

[david@nittedal david]$ ps a

PID TTY STAT TIME COMMAND

420 1 S 0:02 /bin/login -- root

421 2 S 0:02 /bin/login -- root

422 3 S 0:00 /sbin/mingetty tty3

426 5 S 0:00 /sbin/mingetty tty5

427 6 S 0:00 /sbin/mingetty tty6

425 4 S 0:02 /bin/login -- david

685 4 S 0:00 -bash

696 4 S 0:00 sleep 10000

726 p0 S 0:02 /bin/login -h 207.117.119.10 -p

727 p0 S 0:00 -bash

[david@nittedal david]$

Figur 11.4: Eksempel med programmet ps (prosess-status)

Kolonne fra ps Beskrivelse
UID Eier av prosessen
PID Prosessens prosess-id; vet du prosess-id kan du stoppe prosessen ved hjelp av kill-kommandoen.
PPID Moderprosess, eller også kalt Parent Prosess ID
TIME Systemtid brukt av prosessen
STAT Angir status for prosessen (S=sleeping/R=running)
TTY Kontrollerende terminal (enhetsnavn)
COMMAND Navnet på kommando/program
l Viser deg langt format, som inkluderer mer informasjon
t Velg terminal device tty (ps -t5 sjekker tty5)

Prosesstrukturen er hierarkisk bygd opp med foreldre og barn. Prosess nummer 0 er swapper og tilhører root. Dette er den første prosessen som blir startet av operativsystemet. Den neste prosessen er /sbin/init (nummer 1). Denne prosessen er mor til blant annet portmap. Men ser du på prosess 0, så ser du at den er moder (mor) for de fleste andre prosesser, som kflushd, kswapd, syslogd, crond, xinetd, named, lpd etc.

Eksempel:

[vigdis@nittedal david]$ ps ax

PID TTY STAT TIME COMMAND

1 ? S 0:03 init [3]

2 ? SW 0:00 (kflushd)

3 ? SW< 0:00 (kswapd)

421 2 S 0:02 /bin/login -- root

422 3 S 0:00 /sbin/mingetty tty3

743 p0 S 0:02 su - vigdis

744 p0 S 0:01 -bash

822 p0 R 0:01 ps ax

823 p0 S 0:00 more

425 4 S 0:02 /bin/login -- david

685 4 S 0:00 -bash

696 4 S 0:00 sleep 10000

726 p0 S 0:02 /bin/login -h 207.117.119.10 -p

Bundet til terminalen ttyp0, har jeg prosessen su - vigdis. Ønsker du en komplett oversikt over prosesser med tilhørende barneprosesser på systemet som helhet, er kommandoen ps alx nyttig.

Ønsker du en komplett trestruktur over alle barneprosesser til en kjørende prosess kan du bruke kommandoen pstree.

[vigdis@nittedal david]$ pstree -cp 125

Resultatet av denne kommandoen viser alle barneprosessene til httpd-serverprosessen (på min maskin er 125 prosess-id til httpd).

Systemfiler: /dev/mem minne

   /dev/ttxx terminalnavn 

Se også: kill, nice, renice, pstree

Fortsette prosesser etter utlogging – nohup[rediger]

De bakgrunns- og forgrunnsprosesser du starter fra terminalen, stoppes automatisk når du logger deg ut. Har du jobber som skal fortsette når du er utlogget, må de startes med kommandoen nohup.

Kommandoen nohup fortsette prosesser etter utlogging
Kommando: nohup kommando [argument]
Funksjon: Forhindre at prosesser dør når du har logget deg ut
Kommando programmet som skal kjøre i bakgrunnen
Argument: argumentet til kommando

Hvis resultatet av kommandoen ikke blir omdirigert, blir resultatet sendt til filen nohup.out. Har ikke brukeren skrivetillatelse til katalogen, blir resultatet sendt til $HOME/nohup.out, hvor $HOME refererer til brukerens hjemmekatalog, for eksempel /home/david.

Eksempel:

[david@nittedal david]$ nohup regnskap 2001 > resultat &

Her starter jeg programmet regnskap. Tallet 2001 er et argument til programmet regnskap. Eventuelle meldinger fra programmet regnskap blir sendt til filen resultat.

Eksempel: [david@nittedal david]$ nohup ps axl | grep httpd > /tmp/antall.httpd &

Kommandoen grep søker etter tekststrengen httpd fra resultatet av kommandoen ps. Resultatet blir plassert i filen /tmp/antall.httpd. Jeg kan logge meg direkte ut, uten å vente på resultatet av kommandoen.

Kommandoer du starter med nohup-kommandoen, kan du fjerne med kommandoen kill.

Se også: nice, kill, renice, pstree

Stoppe en prosess – kill[rediger]

Et program som startes fra terminalen som en forgrunnsprosess, kan alltid stoppes ved at du trykker på terminalens interrupttast delete eller <Ctrl-C> (PC-konsollet).

For prosesser som går i bakgrunnen, hjelper det ikke å trykke på <Ctrl-C>, du må finne prosessnummeret (PID) og fjerne prosessen med kill-kommandoen. Bare systemadministrator kan stoppe prosesser eid av andre.

Kommandoen nohup fortsette prosesser etter utlogging
Kommandoen kill avslutte prosesser
Kommando: kill [-s signal] pid

kill -l [signal]

Funksjon: Avslutte unødvendige prosesser
Opsjoner: Se også Linux-man-sidene.
-s signal Spesifiser hvilket signal som skal sendes; signalet kan være et nummer eller navn.
-l Skriver ut en liste over signalnavn
pid Prosess-id-nummeret til prosessen

Prosess-id-nummer (PID) er prosessens identifikasjonsnummer. Med ps-kommandoen kan du finne de forskjellige prosessnumrene. Signalnummer avhenger av hva slags prosessor (arkitektur) maskinen din har. Eksempel:

[david@nittedal david]$ kill -l

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL

5) SIGTRAP 6) SIGIOT 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

Et alternativ er å sjekke filen: /usr/include/linux/signal.h. Her er en forklaring på noen av signalnumrene:

Signalnr. Beskrivelse Signalnr. Beskrivelse
1 hangup 2 interrupt
3 quit 4 illegal instruction
5 trace trap 6 IOT instruction
7 EMT instruction 8 floating point exception
9 kill 10 bus error
11 segmentation violation 12 bad argument to system call
13 write on a pipe with no one to read it 14 alarm clock
15 software (soft kill) 16 user defined signal 1
17 death of a child 18 power-fail restart

I mange tilfeller kan det være nødvendig å avslutte en prosess. Det kan for eksempel være bakgrunnsprosesser som har blitt startet med &-tegnet, og som aldri blir ferdig.

Den vanligste situasjonen er at du har en terminal som har hengt seg opp. Når en terminal har hengt seg, hjelper det ikke hva du enn trykker; terminalen tar ikke i mot tastetrykk.

Spesielt i forbindelse med kompleks skjermhåndtering kan en udefinert kontrollsekvens få terminalen til å henge seg opp. Har du en terminal som henger, kan du logge deg inn på en annen terminal (Ctrl, Alt og Funksjonstast<n>=gir deg et annet terminalvindu) med samme bruker-id og utføre ps-kommandoen. Kjenner du terminalnavnet på terminalen som henger, kan du for eksempel skrive

[david@nittedal david]$ ps t4

PID TTY STAT TIME COMMAND

425 4 S 0:02 /bin/login -- david

685 4 S 0:00 -bash

[david@nittedal david]$

Eller få en full status med:

[david@nittedal david]$ ps axl

Begge disse variantene vil gi deg prosess-id til den prosessen som henger. Prosessen avslutter du med kill-kommandoen.

Eksempler:

[david@nittedal david]$ kill -9 425

Avslutter prosess nummer 425. Du kan også avslutte brukerens skall:

[david@nittedal david]$ kill -9 685

Når du avslutter brukerens skall, må brukeren logge seg inn på nytt.

[david@nittedal david]$ kill -15 789

Avbryter prosess 789 med med signalnummer 15. Hvis signalnummer 15 ikke virker, prøv signalnummer 9:

[david@nittedal david]$ kill -9 1

Selv om du er systemadministrator (root), er det ikke mulig å drepe init-prosessen. Linux gir ingen feilmeldinger på denne kommandoen; det skjer rett og slett ikke noe som helst.

Se også: ps, bash, nice, renice, pstree

Endre prioriteten på en prosess – nice[rediger]

Ved å øke prioriten til en prosess, vil prosessen få en større del av CPU-fordelingen, og dermed går prosessen raskere. Redusert prioritert gjør at prosessen får en mindre del av CPU-fordelingen, og dermed går prosessen tregere.

Jo høyere prioritetsnummer, jo lavere blir prioriteten til prosessen. Prioriteten på en kommando angis med tall fra -20 (høyest) til 19 på alle Linux-baserte systemer. På større Unix-systemer angis prioriteten med tall fra -120 til 120. Standard prioritetsverdi er 0.

Vanlige brukere kan bare minske prioriteten på et program og ikke øke den. For å minske prioriteten adderes en verdi til prioritetstallet. Systemadministrator kan kjøre programmer som har høyere prioritet enn normalt, ved å bruke to negative tegn, for eksempel vil --10 gi en nice-verdi på 10, som er en høyere pritoritet enn 0 som er standard.

Kommandoen nice - endring på prosessprioritet
Kommando: nice [-n justering] [-justering] [--justering] kommando [argument]
Funksjon: Forandrer prioriteten på en prosess ved å legge en verdi til prioritetsnummeret
Opsjoner: Se også Linux-man-sidene.
justering Her kan du skrive en differanseverdi eller en justering som er positiv eller negativ [-20..19]. -20 er høyeste prioritering og 19 er den laveste.
Kommando: Her skriver du navnet på programmet som skal endre prioritet.
Argument: Argument til programmet ditt

Eksempler:

[david@nittedal david]$ nice -15 /usr/bin/linux_machine

Systemet vil legge 15 til den opprinnelige verdien på prioritetsnummeret. Det nye prioritetsnummeret for programmet linux_machine blir 0+15=15.

[david@nittedal david]$ nice /bin/calc/numeric

Her angir du ikke noe tall, verdien blir da økt med 10. Den nye verdien blir 0+10=10.

[root@nittedal root]$ nice --10 /bin/c-make

Her starter systemansvarlig et program (c-make). Han trekker 10 fra den opprinnelige prioriteringsverdien på 0. Nytt prioritetsnummer blir dermed 0-10=-10. Programmet /bin/c-make vil dermed kjøres med høyere prioritet enn vanlig.

Med kommandoen renice har du muligheten til å endre prioriteten på en prosess som kjører. Du kan endre prioriteten fra -20 til +20. Syntaksen er lik nice-kommandoen. Under har jeg et eksempel.

[root@nittedal root]$ renice +20 230

I dette eksemplet reduserer jeg prioriteten på prosessen som har prosessnummer 230 med 20.

Se også: nohup, ps, pstree

Tidsforbruk – time[rediger]

Kommandoen time angir hvor lang tid Linux bruker på de forskjellige Linux-kommandoene og på dine egne programmer.

Kommandoen time - tidsforbruk
Kommando: time [argument]
Funksjon: Finner ut hvor lang tid Linux-systemet bruker for å utføre en kommando
Argument: Programmet som skal kjøres
Opsjoner: Se også Linux-man-sidene.

Når kommandoen er utført, får du vite forbrukt tid i sekunder på selve kommandoen; det betyr fra du startet kommandoen til resultatet med ledeteksten kom tilbake til skjermen.

   tid i sekunder som programmet bruker i Linux-systemet
   programmets (overhead) utnyttelse av CPU i sekunder 

Eksempel:

[david@nittedal david]$ time du /home/david

1 /home/david/.tin/.mailidx

1 /home/david/.tin/.index

4 /home/david/.tin

10 /home/david

0.10user 0.07system 0:00.18elapsed 91%CPU (0avgtext+0avgdata 0maxresident)k

0inputs+0outputs (85major+14minor)pagefaults 0swaps

[david@nittedal david]$

Her får jeg vite det totale blokkforbruket fordelt per katalog og tidsforbruket på utføringen av kommandoen. Det første tallet gir brukerbelastningen (0,1 sekunder), andre tallet gir systembelastningen, det tredje tallet er totaltiden med CPU-belastningen (91 % i et intervall på 0,0018). De siste parameterene gir meg swap-belastingen (Linux bruker paging). Du kan se av tallene at swap-belastningen er lik null.

Faste bakgrunnsjobber – crontab[rediger]

Med Linux har du muligheten til å kjøre mange forskjellige typer bakgrunnsjobber som kan kjøres på bestemte tidspunkter. Jeg bruker her crontab-kommandoen til å manipulere mine faste jobber. Eksempler på jobber kan være oppdatering av loggfiler, fjerning av midlertidige filer, kjøring av bestemte e-post-lister, osv.

Dine faste jobber blir lagret i din egen katalog under /var/spool/cron/crontabs. Det er cron-prosessen crond som leser disse faste jobbene og starter programmene på spesifisert tid.

Kommandoen crontab oppdatere jobb-fil
Kommando: crontab [-l] [-r] [-e] [fil]
Funksjon: Oppdatere jobbfil (faste jobber)
Opsjoner: Se også Linux-man-sidene.
fil Navnet på jobb-filen som blir installert
-l Lister en crontab-fil
-r Fjerner din crontab-fil
-e Redigerer en crontab-fil ved å starte standard editor

Hver jobblinje i crontab-filen har seks felt. Alle feltene blir separert med mellomrom, taber eller begge deler.

Felt Beskrivelse
1 minuttet programmet skal kjøres
2 Timen programmet skal kjøres
3 Dagen i måneden programmet skal kjøres
4 Måneden programmet skal kjøres
5 Ukedag programmet skal kjøres (søndag er 0, mandag 1, etc.)
6 Programmet som skal kjøres

Tidsfeltene kan bestå av en kommaseparert liste eller * for å indikere hver eneste periode, f.eks hver time, hver uke, hver måned etc. Du kan legge til kommentarlinjer til crontabs-filen din etter #.

Anta at du har et program (ftp_data_hjemmeside) som skal oppdatere hjemmesiden din på Internett med noen data (bilder, lyd etc.), fire ganger i døgnet alle hverdager. Har du skriptet ferdig, kan crontab enkelt settes opp til å løse den faste jobben.

Eksempel:.

55 6, 12, 18, 23 * * 1-5 ftp_data_hjemmeside

Du ønsker at det skal tas sikkerhetskopi på bånd av Linux-systemet hver natt hele uka. Se eksemplet under:

55 23 * * 0-6 backup_hverdag

Hvis programmet i crontab resulterer i tekst ut til skjerm, og du ikke har overstyrt det til fil eller skriver, vil du automatisk få resultatet i form av e-post.

Du vil finne alle crontab-filene i katalogen /var/spool/cron/crontabs. Er brukernavnet ditt olav, vil du finne crontab-filen din på /var/spool/cron/crontabs/olav.

Root er /var/spool/cron/crontabs/root. Er du logget inn som root, kan du lett addere, redigere eller fjerne bruker-id-er til crontab-kommandolisten.

Hvis du ønsker å sette opp faste bakgrunnsjobber fra GNOME eller KDE grensesnittet er det bare å starte opp kcron-programmet ([root@nittedal /root]# kcron &). Eller du kan trykke på GNOME-knappen, Systemverktøy og Task Scheduler.

Oppgaver til kapittel 11[rediger]

Oppgave 11.1

Hva er forskjellen mellom en forgrunnsprosess og en bakgrunnsprosess?

Oppgave 11.2

Hvilke prosesser går nå? Se hvilke prosesser du er eier av, og finn hvilke prosesser som er foreldre til dine prosesser.

Oppgave 11.3

Start en bakgrunnsprosess, for eksempel med: sleep 500 &, og logg deg ut og deretter inn igjen. Går prosessen fortsatt? Prøv det samme med nohup sleep 500 &.