Inhoudsopgave
Samenvatting
Nu we eindelijk over ons eigen systeem beschikken, kunnen we dieper ingaan op de vraag hoe het eigenlijk funktioneert:
Welke programma's draaien er op mijn computer?
Wat zijn daemons?
Wat is multi-user en multi-tasking processing?
Wat zijn de eigenschappen van processen?
Wat zijn runlevels?
Hoe start en stop ik programma's?
Samenhang tussen programma's.
Hoe kan ik de snelheid en de responstijd van mijn systeem beïnvloeden?
Hoe kan ik taken automatisch laten uitvoeren?
Op een UNIX systeem, zoals onze Ubuntu Linux, zijn er twee grote entiteiten. Enerzijds heb je bestanden. Alle soorten objecten op het systeem, zoals gewone bestanden, mappen, links, speciale bestanden om met randapparatuur te communiceren enzovoorts, worden zoveel mogelijk behandeld onder de algemene noemer “bestand”. Bestanden op zichzelf doen niets, ze staan gewoon op de harde schijf of op een ander opslagmedium. We hebben processen nodig om de bestanden te manipuleren, zodat we een werkbare omgeving krijgen.
Processen zijn altijd uitvoerbare bestanden, die in het geheugen geladen worden en daar instructies doorgeven naar de processor. Neem er nog even hoofdstuk drie uit lespakket 1 bij: uitvoerbare bestanden hebben een “x” in minstens één van de groepen “user”, “group” of “other”. Nemen we als voorbeeld het commando ls:
willy@ubuntu:~$whichls/bin/lswilly@ubuntu:~$ls-l/bin/ls-rwxr-xr-x 1 root root 71912 2005-09-05 11:14 /bin/ls
Zolang niemand het ls commando gebruikt om een lijst van bestanden op te vragen, is ls gewoon een bestand. Maar omdat het uitvoerbaar is, kan het instructies beginnen geven aan de processor, wanneer het door de shell opgeroepen wordt. Zolang ls in het geheugen zit en instructies uitdeelt, is het een process.
Sommige commando's starten een enkel proces, zoals ls. Andere commando's starten een hele serie processen. Een voorbeeld van zo'n proces is je web browser. Bovendien kan je meerdere processen tegelijk opstarten: een terminal venster, een browser, een E-mail programma, een tekenprogramma, enzovoort. Dit fenomeen heet multi-tasking, letterlijk: veel taken uitvoeren.
Naast deze eigenschap beschikt Linux, net zoals UNIX, waarvan het afgeleid is, over de mogelijkheid om verschillende gebruikers tegelijk te bedienen. Die gebruikers kunnen lokaal werken via het scherm, het toetsenbord en de muis, of ze kunnen vanop het netwerk verbinden met de computer, of ze kunnen afzonderlijke schermen en toetsenborden hebben, terminals genaamd. Dat is de multi-user funktie van het systeem, letterlijk: veel gebruikers.
![]() | Terminals, is dat niet ouderwets? |
|---|---|
Bijvoorbeeld in de Colruyt, waar elke kassier via een terminal op de hoofdcomputer werkt, worden terminals veel gebruikt. |
Het is duidelijk dat er een methode moet zijn om alle processen van alle gebruikers in toom te houden: we willen niet dat één gebruiker alle geheugen van de computer gebruikt, of alle ruimte op de harde schijf, of alle kracht van de processor, want dan kunnen de andere gebruikers niet meer werken. Er moet ook funktionaliteit voorzien worden zodat gebruikers nu eens het ene programma, dan weer het andere kunnen gebruiken, zonder de programma's telkens te moeten afsluiten. Soms moet er ook voor gezorgd worden dat programma's blijven doordraaien, zelfs als de gebruiker zich afmeldt.
In de volgende paragrafen geven we een overzicht van deze funktionaliteit.
Interactieve processen worden gestart en gecontroleerd vanuit een terminal sessie. Met andere woorden: er moet iemand aangemeld zijn op het systeem, lokaal of via het netwerk, om het proces te kunnen starten; een interactief proces wordt niet automatisch opgestart als onderdeel van de initialisatie van het systeem.
Interaktieve processen kunnen draaien in de voorgrond, dat wil zeggen dat ze de terminal bezet houden vanwaar ze opgestart zijn. Zolang het proces draait, kan je in dat terminal venster geen ander proces opstarten. Een voorbeeld:

willy@ubuntu:~$find/usr-nametest
Het doorzoeken van de /usr map duurt even, zolang kan je niets doen in datzelfde venster. Je kan uiteraard wel een ander terminal venster openen en daar verder werken. Een ander voorbeeld is het bekijken van een bestand met less. Tot nu toe hebben we vooral met processen in de voorgrond gewerkt, hoewel de tijd die nodig was om een programma uit te voeren dikwijls zodanig kort was dat je misschien niet hebt gemerkt dat het proces de terminal bezet hield.
Alternatief kunnen processen ook in de achtergrond draaien. In dat geval wordt de terminal niet bezet gehouden en kan je andere taken uitvoeren terwijl het programma aktief is.
De shell heeft een speciaal mechanisme, job control, die het gemakkelijk maakt om meerdere processen te behandelen. Dit mechanisme zorgt ervoor dat het proces dat je nodig hebt in de voorgrond draait.
Een proces in de achtergrond draaien is enkel nuttig voor die programma's die geen input nodig hebben. Een proces wordt typisch in de achtergrond gedraaid wanneer men verwacht dat het lang zal duren eer het proces zijn taken vervuld heeft.
Een proces in de achtergrond plaatsen doe je door in de shell achter het opgegeven commando een ampersant te plaatsen. Bijvoorbeeld:

willy@ubuntu:~$xterm & [1] 7990willy@ubuntu:~$
Bovenstaand commando start een eenvoudiger type van terminal venster, waarin je opdrachten kan geven. In het venster vanwaar je het programma hebt opgestart, krijg je de prompt terug en je kan verder werken. We zien meteen ook al een eerste procesattribuut: het procesidentificatienummer, kortweg PID. Het PID van het eerste commando dat in de achtergrond draait is hier 7990. Het wordt voorafgegaan door het jobnummer, hier 1, tussen vierkante haken.
Elk proces heeft een PID, we bespreken zodadelijk hoe we aan de hand van deze informatie processen kunnen manipuleren.
![]() | Jobnummer vs. procesnummer |
|---|---|
Het jobnummer wordt door de shell gebruikt (zie tabel), zodat e als gebruiker geen lange getallen hoeft in te geven om processen te beheren. |
De volgende tabel geeft een overzicht van de commando's en deelcommando's die gebruikt worden om processen te switchen tussen de voorgrond en de achtergrond.
Tabel 5.1. Processen controleren
| (deel van) Commando | Betekenis |
|---|---|
| commandonaam | Draait het commando in de voorgrond. |
| commandonaam & | Draait het commando in de achtergrond en geeft de terminal vrij. |
| jobs | Toon de commando's die in de achtergrond aan het draaien zijn. |
| Ctrl+Z | Bevries het commando (in het Engels: suspend). |
| Ctrl+C | Beëindig het commando dat in de voorgrond draait. |
%n | Elk commando in de achtergrond krijgt een jobnummer (in bovenstaand voorbeeld: 1). Gebruik de uitdrukking % met dit nummer om naar een proces te verwijzen, bv. fg %2 om het tweede in de achtergrond geplaatste commando weer in de voorgrond te zetten. |
| bg | Aktiveer een bevroren commando terug, na Ctrl+Z. |
| fg | Breng een commando van de achtergrond naar de voorgrond. |
| kill | Beëindig een programma dat in de achtergrond draait. |
Op het kill commando komen we zodadelijk nog terug.
![]() | Oefenen |
|---|---|
|
Naast interactieve processen, opgestart door de gebruikers van een systeem, zijn er ook automatische of batch processen. Die worden niet opgestart vanuit een terminal venster. Ze wachten eerst op uitvoering in een daartoe bestemde map. Vandaaruit worden ze opgeroepen door een programma dat de wachtrij analyzeert en de programma's systematisch uitvoert. Het programma dat het eerste in de wachtrij terecht kwam, wordt ook eerst uitgevoerd. De naam van dit systeem is “FIFO”, wat staat voor “first in, first out”.
Er zijn twee manieren om automatische processen uit te voeren:
Op een gegeven datum en tijd: dit gebeurt door middel van het at commando.
Alternatief kan met het aan het systeem overlaten om te bepalen wanneer een goed moment is om automatische taken uit te voeren door gebruik te maken van het batch commando.
De eerste methode is ook voor gewone gebruikers nuttig en wordt later in dit hoofdstuk besproken. De tweede methode wordt meestal in grotere omgevingen toegepast en is veeleer een werk voor systeembeheerders en zware gebruikers; vandaar valt die methode buiten de scoop van deze cursus.
Daemons, Engels voor “demonen”, zijn serverprocessen die continu draaien. Meestal worden ze opgestart wanneer het systeem opstart, waarna ze in de achtergrond wachten tot hun diensten vereist zijn.
Zelfs als je zelf geen servers draait op je thuis-PC, zijn er daemons aktief. Een voorbeeld is de daemon die nagaat of je wilt inloggen: zelfs als je nog niet aangemeld bent, draait dit proces. Zo is er ook een netwerkdaemon die constant “luistert” of er geen netwerkverbindingen moeten gemaakt worden.
Elk proces heeft een aantal vaste eigenschappen:
Het procesidentificatienummer of PID: een uniek nummer dat gebruikt wordt om naat het proces te verwijzen.
Het PID van het proces dat dit proces gestart heeft: parent process ID of PPID- letterlijk: het PID van de ouder.
Het zogenaamde nice number: de mate van vriendelijkheid van dit proces: laat het nog veel processorcapaciteit over aan andere processen, of juist niet?
De terminal van waaruit dit proces opgestart werd, als het om een interaktief proces gaat. Dit wordt aangeduid met een tty number.
De gebruikersnaam van de gebruiker aan wie het proces toebehoort.
De groepsnaam van de groep aan wie het proces toebehoort.
Noteer dat de gebruikersnaam bestaat uit een echte gebruikersnaam (real username of RUID) en een effectieve gebruikersnaam (effective username of EUID). De echte gebruiker is diegene die het commando opstartte, de effectieve gebruikersnaam bepaalt de toegangsrechten. Gewoonlijk zijn RUID en EUID hetzelfde, en het proces heeft dezelfde toegangsrechten als de gebruiker. Een voorbeeld om duidelijk te maken wat hiermee bedoeld wordt: de browser firefox:

willy@ubunty:~$whichfirefox/usr/bin/firefoxwilly@ubunty:~$ls-l/usr/bin/firefoxlrwxrwxrwx 1 root root 30 2006-06-06 14:17 /usr/bin/firefox -> ../lib/mozilla-firefox/firefoxwilly@ubunty:~$ls-l/usr/libmozilla-firefox/firefox-rwxr-xr-x 1 root root 11170 2005-10-10 17:31 /usr/lib/mozilla-firefox/firefox
Wat zien we hier?
firefox zit in de /usr/bin map.
/usr/bin/firefox is een symbolische link naar /usr/lib/mozilla-firefox/firefox.
De eigenaar van dat bestand is root.
![]() | Wie ben ik? |
|---|---|
Gebruik het id commando om na te gaan als welke gebruiker je aan het werken bent. |
De systeembeheerder, root, is de baas van het systeem en heeft alle rechten op alle bestanden. Men zou dus op het eerste zicht kunnen denken dat je met firefox meer zou kunnen dan met bijvoorbeeld het cat commando.

Probeer maar eens cat /etc/shadow, dus het bekijken van het bestand waarin de versleutelde wachtwoorden van alle gebruikers van het systeem zitten. Je zal zien dat dit niet lukt. Ook als je in firefox de URL file:///etc/shadow ingeeft, gebeurt er niet veel. Dit komt omdat je de browser opstart met je eigen toegangsrechten, en niet met die van de eigenaar van het commando (kan je nagaan m.b.v. ps -ef). Gelukkig maar, of het hele systeem van toegangsrechten zou op losse schroeven komen te staan.
Hetzelfde geldt voor de toegangsrechten van de groep die eigenaar is van het commando en jouw eigen groepsnaam, waarmee je het commando opstart.
Een van de meest gebruikte commando's voor het opvragen van procesinformatie is ps (afkorting van het Engelse “process”). Zonder opties krijg je enkel de processen te zien die verbonden zijn met de terminal sessie vanwaaruit je ps oproept:

willy@ubunty:~$ ps
PID TTY TIME CMD
7268 pts/0 00:00:00 bash
8240 pts/0 00:00:00 xterm
8266 pts/0 00:00:00 xcalc
9855 pts/0 00:00:00 ps
Noteer: de commando's die in de vorige oefening werden opgestart, zijn hier nog aktief.
We zien 4 kolommen met informatie:
PID: het procesidentificatienummer.
TTY: het terminal type en nummer waaraan het proces verbonden is. Wij gebruiken pts, pseudo-terminals, in tegenstelling tot echte terminals waarbij je een toetsenbord en een scherm hebt, waarmee je niets anders kan doen dan 1 enkele shell openen, in een tekstuele omgeving (te vergelijken met DOS vroeger). Pseudo-terminals zijn terminal vensters in een grafische omgeving, of verbindingen vanop een netwerk.
TIME: een relatieve indicatie van de tijd die het aantal processorcycli dat het process al verbruikt heeft. Gewone processen van gebruikers verbruiken slechts een klein deel van de totale processorkracht.
CMD: de naam van het commando.
Normaalgezien draaien er tientallen, honderden of duizenden processen op een systeem. We hebben dus manieren nodig om die processen uit te filteren die voor ons van belang zijn, tesamen met de bijhorende procesinformatie. Dit doen we door opties bij ps te gebruiken en dan de shell te gebruiken om de resultaten te filteren.
Het meest gebruikt is wellicht de constructie
ps -ef
![]() | Voer uit |
|---|---|
Geef dit commando in in een terminal venster. Rol de schuifbalk aan de rechterzijkant van het venster naar boven toe, totdat je ziet waar de output van dit commando begint. |
Op een systeem zoals hetgeen waarmee je nu werkt, valt de lijst van processen nog mee. Je krijgt een lijst met 8 kolommen te zien, waarvan deze het meest relevant zijn:
UID: de naam van de gebruiker die het proces opstartte.
PPID: procesidentificatienummer van het parent process, het proces dat dit proces opstartte.
TTY: de terminal waaraan het proces verbonden is, “?” wil zeggen dat het proces niet aan een terminal verbonden is.
CMD: de volle naam van het commando waarmee het proces werd opgeroepen.
De man pagina van ps bevat veel voorbeelden van het gebruik van de andere opties. Je vindt er ook meer uitleg over de informatie in de andere kolommen. In het volgende hoofdstuk gaan we verder in op het filteren van de output, zodat er meer relevante informatie getoond wordt. We willen namelijk niet elke keer gaan zoeken in deze lijst naar het specifieke proces dat we onder de loupe willen nemen.
Het top commando geeft min of meer dezelfde informatie als ps -ef, maar hier wordt de informatie om de vijf seconden opgefrist. Bovendien hebben we hier al automatisch een zeker vorm van sorteren: de zwaarste processen, dat wil zeggen de processen die het meeste processortijd verbruiken, worden bovenaan in de lijst getoond. We krijgen ook niet alle processen te zien. Al naargelang de grootte van je terminal venster wordt de lijst ingekort. We krijgen dus een “top” van de processen te zien.
![]() | Meedoen |
|---|---|
Geef het top commando in, zonder opties, gevolgd door Enter. We bespreken hieronder verder de output. |
Naast de info over de processen, onder de zwarte balk, zien we bovenaan nog een aantal andere gegevens over het systeem:
De output van het uptime commando, met daarin informatie over hoe lang het systeem al draait, hoeveel gebruikers er verbonden zijn en wat de belasting is, zie ook de paragraaf “Belasting”. Meer info in man uptime.
Het aantal processen en de status ervan: er draait altijd slechts 1 proces tegelijk op de CPU, terwijl de andere in een wachtrij staan. Zo werkt multitasking: de processor neemt een proces uit de wachtrij, helpt het een beetje verder en plaatst het weer in de wachtrij, om het volgende proces een beetje verder te helpen. Dit alles gaat echter zo snel, dat het lijkt alsof er tientallen of zelfs honderden processen tegelijk draaien.
De belasting van de processor(s): moet de processor veel berekeningen maken, dan is de belasting hoog. Als de processor gewoon data moet doorgeven, zonder er zware bewerkingen op uit te voeren, is de belasting laag. Programma's die veel rekenkracht vereisen, zoals toepassingen voor grafische beeldverwerking en analyzeprogramma's vergen veel van de processor. Zo zal het zwaarste programma op jouw systeem waarschijnlijk X zijn, de grafische server die ervoor zorgt dat alle vensters op je bureaublad staan en dat de juiste gegevens in het juiste venster verschijnen.
Gebruik van het geheugen: alle programma's die aktief zijn, nemen een plaatsje in op het geheugen.
Gebruik van de swap space (het virtuele geheugen, zie de paragraaf “Schijfindeling”): als er teveel programma's draaien, wordt alle beschikbare plaats in het geheugen opgevuld. Een speciale plek op de harde schijf wordt dan gebruikt als extra geheugen.
![]() | Documentatie |
|---|---|
Lees man |
We hebben het al enkele keren over parent processes gehad. Waar komen onze processen vandaan? Gebruik het pstree commando om de processtructuur te tonen.
De meeste processen stammen af van init, het initiële proces waarmee het systeem gestart wordt. Meer hierover in de paragraaf “Hoe je computer opstart en afsluit”.
![]() | Waar is pstree? |
|---|---|
Voer het pstree commando in in een terminal venster, gevolgd door Enter. Waar zit het pstree commando zelf in deze boomstructuur? Welk proces is de ouder (het parent process) van pstree? |
Een nieuw proces wordt aangemaakt doordat een bestaand proces een exacte kopie van zichzelf maakt. Dit child process (letterlijk: het kind van het ouderproces) is eigenlijk net hetzelfde als het ouderproces, enkel het procesidentificatienummer verschilt. Deze procedure heet men een fork (letterlijk: een vork of splitsing).
Na de fork wordt de geheugenruimte van het kindproces overschreven met de nieuwe procesdata: het commando dat gevraagd werd, wordt in het geheugen geladen. Dit noemt men een exec.
Het geheel van kopiëren en overschrijven heet dan fork-and-exec. Alle processen worden op deze manier gemaakt. Zelfs init, het eerste proces met PID 1, werd zo gecreëerd door de kernel.
Onderstaand schema geeft weer hoe bijvoorbeeld een ls proces afstamt van je shell, bash:
De fork wordt hier met een horizontale pijl voorgesteld. Bemerk dat enkel het procesidentificatienummer verandert.
De vertikale pijlen stellen de exec voor. Hier blijft het procesidentificatienummer gelijk, maar de geheugeninhoud wordt verwisseld.
Zoals we reeds konden zien aan de output van het pstree commando, hebben veel processen init als ouderproces, terwijl dat helemaal niet mogelijk is. Nemen we bijvoorbeeld ons systeem dat in grafische mode draait: er moeten allerlei programma's opgestart worden om het grafische loginscherm te tonen, daarna moet de desktop gestart worden door middel van een desktopmanager, dan volgt de venstermanager (windowmanager), dan start je een terminal venster en daarin draait een shell waarmee je commando's kan ingeven. Wat gebeurt hier dan?
De verklaring is tamelijk eenvoudig: veel programma's “demoniseren” hun kindprocessen, zodanig dat die kunnen blijven draaien als de ouder stopt (zie de paragraaf “Daemons”). Het init proces neemt de rol van peetvader van zulke processen: als de ouder sterft, vallen ze onder de verantwoordelijkheid van init.
![]() | Voorbeeld van demoniseren |
|---|---|
|
Heel af en toe wil het nog wel eens mislopen met de “adoptie” van processen. Een proces dat geen ouderproces heeft, noemt men een zombie. Je kon deze term ook zien in de output van het top commando. Het systeem heeft geen vat meer op zo'n zombieproces, het blijft in het geheugen hangen tot je de computer herstart. Meestal duidt het voorkomen van zombieprocessen op slecht geprogrammeerde applicaties.
Wanneer een proces normaal eindigt, geeft het een code, de exit status, door aan de ouder. Als alles goed verlopen is, is de exit status nul. Men mag ervan uitgaan dat er iets foutliep als de exit status niet nul is. De mogelijke waarden van de exit status worden gedocumenteerd in de man pages en de systeembibliotheken. Ze zijn voor elk commando verschillend en worden bijvoorbeeld in scripts gebruikt om na te gaan of een opdracht al dan niet gelukt is. Ook programmeurs maken veelvuldig gebruik van de exit status van commando's.
De waarde van de exit status van shell commando's wordt opgeslagen in een speciale variabele, aangeduid met $?. Met het echo commando kan je de inhoud van deze variabele bekijken.
Hieronder een voorbeeld met grep. Een exit status van 0 betekent dat de zoekstring gevonden werd in het opgegeven bestand:

willy@ubuntu:~$grepwilly/etc/passwdwilly:x:1000:1000:Willy,,,:/home/willy:/bin/bashwilly@ubuntu:~$echo$?0
![]() | /etc/passwd? |
|---|---|
Het
|
Een exit status van 1 betekent dat de zoekstring niet gevonden werd, maar niet noodzakelijk dat de shell een foutmelding geeft:

willy@ubuntu:~$grepblah/etc/passwdwilly@ubuntu:~$echo$?1
Een exit status van 2 lokt wel een foutmelding uit, bijvoorbeeld wanneer de optie niet herkend wordt of het opgegeven bestand niet gevonden wordt:

willy@ubuntu:~$grepblah/etc/blablagrep: /etc/blabla: Onbekend bestand of mapwilly@ubuntu:~$echo$?2willy@ubuntu:~$grep--blahbleble/etc/passwdgrep: optie niet herkend `--blah' Gebruik: grep [OPTIE]... PATROON [BESTAND]... Probeer `grep --help' voor meer informatie.willy@ubuntu:~$echo$?2
Deze methode om een gecodeerd resultaat terug te geven stamt van de C programmeertaal. Vandaar dat de code ook wel eens return code genoemd wordt.
Processen eindigen omdat ze een signaal krijgen. Je kan verschillende signalen naar een proces sturen. Om dat te doen gebruik je het kill commando (zie de paragraaf “Het kill commando”). Met de optie -l krijg je een lijst van de mogelijke waarden van de signalen. De meeste worden echter intern door de programma's op je systeem gebruikt. Als gewone gebruiker heb je doorgaans enkel de volgende signalen nodig:
Tabel 5.2. Signalen
| Naam | Waarde | Betekenis |
|---|---|---|
| SIGTERM | 15 | Beëindigt het proces op een ordelijke manier. |
| SIGINT | 2 | Onderbreek het proces. Een proces kan dit signaal negeren. |
| SIGKILL | 9 | Onderbreek het proces. Een proces kan dit signaal niet negeren. |
| SIGHUP | 1 | Voor demonen: laat het proces zijn configuratiebestand(en) opnieuw inlezen. |
We gaan zodadelijk verder in op het gebruik van de signalen.
Je kan meer lezen over hoe een proces op een bepaald signaal zal reageren in man signal.