Prozesse - Koblenz

Transcrição

Prozesse - Koblenz
Übung zu Grundlagen der
Betriebssysteme
6. Übung
20.11.2012
Prozess & Programm
Erläutern Sie den Begriff Prozess und unterscheiden Sie die Begriffe Prozess und Programm
voneinander.
•
Verwaltet ein in Ausführung befindliches Programm und die dazugehörigen
Betriebsmittel
→ die Abstraktion eines Programms während der Ausführung
•
Prozesse befinden sich immer in genau einem der folgenden Zustände:
Prozess & Programm
Prozess & Programm
Prozesse sind • aktive Komponenten
• befinden sich in Ausführung
• können voneinander abhängen
• zwischen Prozessen kann es Konflikt-Situation geben
• benutzen Ressource (Betriebsmittel)
• Prozessinterkommunikation ermöglicht Synchronisation zwischen Prozessen
• haben einen Zustand
• Strategien legen fest, wie mit Prozessen verfahren wird
Vorlesung: Prof. Frey: 04-processes, S.5
Aufgabe 1
a) Erläutern sie mit wenigen Worten die 5 Zustände eines Prozesses aus dem
Prozesszustands-Diagramm.
b) Gehen sie auf den Zustand „waiting“ näher ein und erläutern und begründen sie mit
wenigen Worten, ob auf diesen Zustand auch verzichtet werden könnte!
Aufgabe 1
new + terminated:
• Prozesse, die den Rechner gerade betreten bzw., ihn nach vollständiger Bearbeitung
verlassen.
• Sie entstehen, wenn ein neuer Benutzer sich "einloggt", ein bestehender Prozess einen
Subprozess bildet oder ein Dienst angeboten wird.
• Ein initiierter Prozess gleicht dem Zustand ready, allerdings mit dem Unterschied, das in der
Prozesstabelle noch kein Eintrag für einen Prozesskontrollblock existiert.
• Terminierte Prozesse werden in der Regel mit allen Datenstrukturen gelöscht.
• In UNIX wird der Prozesskontrollblock allerdings solange gespeichert, wie der unmittelbare
Elternprozess läuft. Dieser hat die Möglichkeit mit einem Systemaufruf den
Terminierungsstatus zu erfragen
Aufgabe 1
ready:
• Prozesse, die ihren Ablauf fortsetzen können, befinden sich im Zustand ready. Sie
warten lediglich auf die Prozessorzuteilung
• Der Prozess besitzt alle Ressourcen und wartet auf die Zuteilung eines Prozessors
Aufgabe 1
running:
• Im Zustand running wird der Prozess auf dem Prozessor ausgeführt
Aufgabe 1
waiting:
• Prozesse im Zustand waiting warten auf bestimmte Ereignisse, die für den weiteren
Prozessablauf notwendig sind, z.B. Zuteilung von Speicherplatz, und sind daher
blockiert.
• Wird auch als bedingtes Umschalten bezeichnet, weil der Prozesswechsel davon
abhängt, ob eine Bedingung erfüllt ist. Ein Problem existiert jedoch darin, dass
zwischen Auswertung der Bedingung und der darauffolgenden Aktion ein
Prozesswechsel stattfinden kann. Hier müssen dann Mechanismen der
Prozesskoordination greifen.
• Blockierte Prozesse konkurrieren mit anderen Prozessen um die Zuteilung des
Prozessors.
Aufgabe 1
Ist waiting notwendig?
Process Control Block
Informationen über einen Prozess werden im Process Control Block (PCB) gehalten:
Der PCB enthält unter anderem:
• Prozesszustand
• Registerinhalte der CPU, z.B. Befehlszähler und Stack-Zeiger
• Zugeordnete Hauptspeicherbereiche, z.B. für den Programm-Code und den
Datenbereich, z.B. für globale Variablen
• Zugeordnete Ressource, z.B. Peripheriegeräte und geöffnete Dateien
• Prozesserzeugniszeitpunkt
• Priorität
• Verbrauchte Rechenzeit
• User-ID → die Nummer des Benutzers dem der Prozess gehört
• Prozess-ID des Vaterprozesses
• Umgebung des Prozesses, u.a. das Arbeitsverzeichnis
Prozess-Tabelle (Linux -> top)
top - 13:53:20 up 21 days, 41 min, 2 users, load average: 0.00, 0.01, 0.05
Tasks: 67 total,
1 running, 66 sleeping,
0 stopped,
0 zombie
Cpu(s): 0.0%us, 0.3%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem:
1025336k total,
382160k used,
643176k free,
90452k buffers
Swap:
511996k total,
7612k used,
504384k free,
240620k cached
PID
592
31164
1
2
3
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
USER
syslog
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
root
PR
20
20
20
20
20
20
RT
RT
0
0
20
0
20
20
0
0
0
20
0
20
20
NI VIRT RES SHR S %CPU %MEM
0 30432 980 980 S 0.3 0.1
0 2724 1088 864 R 0.3 0.1
0 3508 1544 1120 S 0.0 0.2
0
0
0
0 S 0.0 0.0
0
0
0
0 S 0.0 0.0
0
0
0
0 S 0.0 0.0
0
0
0
0 S 0.0 0.0
0
0
0
0 S 0.0 0.0
-20
0
0
0 S 0.0 0.0
-20
0
0
0 S 0.0 0.0
0
0
0
0 S 0.0 0.0
-20
0
0
0 S 0.0 0.0
0
0
0
0 S 0.0 0.0
0
0
0
0 S 0.0 0.0
-20
0
0
0 S 0.0 0.0
-20
0
0
0 S 0.0 0.0
-20
0
0
0 S 0.0 0.0
0
0
0
0 S 0.0 0.0
-20
0
0
0 S 0.0 0.0
0
0
0
0 S 0.0 0.0
0
0
0
0 S 0.0 0.0
TIME+
0:37.74
0:00.01
0:00.71
0:00.00
0:08.40
0:00.30
0:00.00
0:07.00
0:00.00
0:00.00
0:00.00
0:00.00
0:03.08
0:00.09
0:00.00
0:00.00
0:00.00
0:00.00
0:00.00
0:13.45
0:00.31
COMMAND
rsyslogd
top
init
kthreadd
ksoftirqd/0
kworker/u:0
migration/0
watchdog/0
cpuset
khelper
kdevtmpfs
netns
sync_supers
bdi-default
kintegrityd
kblockd
ata_sff
khubd
md
kworker/0:1
kworker/u:1
Prozess-Tabelle (Linux -> htop)
Prozess-Tabelle (Windows -> Task-Manager)
•
Leerlaufprozess
Leerlaufprozess
•
Der Leerlaufprozess (engl. idle task) ist ein „Pseudo“-Prozess, der in vielen
Betriebssystemen immer dann Prozessorzeit bekommt, wenn kein anderer Prozess
ausgeführt wird.
•
In dem Betriebssystem Windows wird der Leerlaufprozess
im Taskmanager im Reiter „Prozesse“ immer angezeigt und
zeigt ungenutzte Rechenzeit, also die Kapazität, die nicht
von Anwendungen beansprucht wird.
•
Die Summe der Anteile aller laufenden Prozesse an der Prozessorauslastung
(einschließlich des Leerlaufprozesses) beträgt daher immer 100 %.
•
Auf unixähnlichen Betriebssystemen ist in der Regel das KommandozeilenProgramm top installiert, das in der dritten Zeile einen mit id (für idle task, s. o.)
markierten Wert für den prozentualen Anteil des Leerlaufprozesses an der
Gesamtauslastung aller Prozessoren des Systems ausgibt.
Aufgabe 2
a) Kompilieren und Starten sie das folgende Programm „father_son.c“ unter Linux und
erläutern Sie die Ausgabe im Bezug auf die Variable „i“.
Beziehen Sie sich dabei auch auf die Zeile if (fork() ) und was hier passiert.
#include <stdio.h>
#include <stdlib.h>
int i;
int rnd;
void main(){
if (fork())
for (i=0; i<500; i++){
printf("\n Father: %i", i);
sleep(1);
}
else
for (i=0; i<500;i++){
printf("\n Son: %i", i);
rnd=rand();
sleep(rnd%3);
}
}
Aufgabe 2
bs@bsuebung:~$ ./father_son
Father:
Son: 0
Father:
Son: 1
Son: 2
Father:
Son: 3
Father:
Son: 4
Father:
Son: 5
Father:
Son: 6
Son: 7
Son: 8
Father:
Son: 9
Father:
Father:
Son: 10
Father:
Son: 11
Father:
Father:
Son: 12
Father:
Son: 13
0
1
2
3
4
5
6
7
8
9
10
11
12
Aufgabe 2
bs@bsuebung:~$ ./father_son
Father:
Son: 0
Father:
Son: 1
Son: 2
Father:
Son: 3
Father:
Son: 4
Father:
Son: 5
Father:
Son: 6
Son: 7
Son: 8
Father:
Son: 9
Father:
Father:
Son: 10
Father:
Son: 11
Father:
Father:
Son: 12
Father:
Son: 13
0
1
2
3
4
5
6
7
8
9
10
11
12
Aufgabe 2
b) Der Befehl ps -elf --forest gibt ihnen eine Tabelle mit verschiedenen Spalten aus.
Recherchieren sie die Angabe in den folgenden Spalten und erläutern sie sie mit wenigen
Worten.
(1) F
(2) S
(3) UID
(4) PID
(5) PPID
(6) PRI
(7) SZ
(8) WCHAN
(9) TIME
(10) CMD
Aufgabe 2
root@bsuebung:~# ps
F S UID PID PPID
...
0 S bs
2129 1934
1 S bs
2130 2129
4 R root 2164 1431
-elf
C PRI NI ADDR SZ WCHAN
0
0
0
80
80
80
0 0 0 -
STIME TTY
TIME
CMD
454 hrtime 10:51 pts/1 00:00:00 ./father_son
454 hrtime 10:51 pts/1 00:00:00 ./father_son
1252 10:52 pts/0 00:00:00 ps -elf
-e → select all processes, Identical to -A
-l → long format
-f → full-format listing
ps -elf
-e
listet alle Prozesse des Systems auf
-lf
beeinflussen lediglich die Formatierung der Ausgabe
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Aufgabe 2
Erweitern Sie das Programm „father_son.c“ so, das die Variable „i“ in einem gemeinsamen
Speicher abgelegt wird und alle erzeugten Prozesse auf eine Variable zugreifen und diese
hoch zählen. (Benutzen Sie für die Lösung POSIX Shared Memory).
Aufgabe 2
#include
#include
#include
#include
#include
#include
<stdio.h>
<sys/types.h>
<sys/ipc.h>
<sys/shm.h>
<sys/wait.h>
<stdlib.h>
#define MAXCOUNT 1000000
#define SHMSEGSIZE sizeof(int)
int main(){
int i, shmID, *shared_mem, count=0, total=0,rnd;
shmID = shmget(IPC_PRIVATE, SHMSEGSIZE, IPC_CREAT | 0644);
shared_mem = (int*)shmat(shmID,0,0);
*shared_mem = 0;
if (fork())
for (i=0; i<500; i++){
*shared_mem+=1;
printf("\n Father: %i", *shared_mem);
sleep(1);
}
else
for (i=0; i<500;i++){
*shared_mem+=1;
printf("\n Son: %i", *shared_mem);
rnd=rand();
sleep(rnd%3);
}
shmdt(shared_mem);
shmctl(shmID, IPC_RMID, 0);
return 0;
}
Aufgabe 2
Erläutern Sie mit wenigen Worten welches neue Problem mit der Lösung von Aufgabe 2d)
bzgl. der Variable i und der darauf zugreifenden Prozesse entstanden ist!
Aufgabe 2
:~# ./fatherSonShared
Father:
Son: 2
Father:
Son: 4
Son: 6
Father:
Son: 7
Father:
Son: 9
Father:
Son: 11
Father:
Son: 13
Son: 15
Son: 16
Father:
Son: 17
Father:
Father:
Son: 19
Father:
Son: 22
Father:
Father:
Son: 24
Father:
Son: 27
Father:
Father:
Son: 29
Father:
Son: 32
Son: 34
Son: 35
Father:
1
3
5
8
10
12
14
18
20
21
23
25
26
28
30
31
33
Interprozesskommunikation (IPC)
Systembefehle für Shared Memory
•
#include <sys/shm.h>
shmget (allocates shared memory)
→ legt ein neues Segment an bzw. greift auf ein bestehendes Segment zu.
•
shmat (shared memory attach)
→ hängt ein Shared Memory-Segment an den Adressraum eines Prozesses an.
•
shmdt (shared memory detach)
→ entfernt ein Shared Memory-Segment aus
dem Adressraum des aufrufenden Prozesses.
•
shmctl (shared memory control)
→ führt Steuerungsfunktionen auf einem
Shared Memory-Segment durch.
Interprozesskommunikation (IPC)
Shared Memory
Aufgabe 3
Über die Manpage des Befehls ps (man ps) können sie die verschiedenen Prozess-State-Codes ablesen, die
ein Prozess einnehmen kann.
Kompilieren und Starten sie das folgende Programm ynlahd.c
# gcc -o ynlahd ynlahd.c
-> ./ynlahd
#include
#include
#include
#include
<stdlib.h>
<unistd.h>
<stdio.h>
<wait.h>
int main ()
{
if (fork()) { //Father process
printf("Father waits\n");
sleep(60);
printf("Father stops waiting\n");
}
else { //Son process
printf("Son starts\n");
int i=0;
for(i=0;i<=10;i++) printf("Son counts %d\n",i);
printf("Son exits\n");
exit (1);
}
return 0;
}
Aufgabe 3
•
•
•
•
Welcher besondere Zustand wird hier vom "Son"-Prozess eingenommen?
Betrachten Sie während der Laufzeit des obigen Programms die Prozess-Status Tabelle mit ps –elf.
Geben Sie den relevanten Teil der Ausgabe hier an.
Was ist besonders an dem Zustand des "Son"-Prozesses.
F S UID
PID
PPID
C PRI NI ADDR SZ WCHAN
0 S root 15344 14679 0 80
0
-
1 Z root 15345 15344 0 80
0
-
4 R root 15350 15289 0 80
0
-
STIME TTY
TIME
CMD
454 hrtime 16:24 pts/0 00:00:00 ./ynlahd
0 exit
1253 -
16:24 pts/0 00:00:00 [ynlahd]<defunct>
16:25 pts/1 00:00:00 ps -elf
Aufgabe 3
Zombie-Prozess:
Als Zombie wird ein Prozess bezeichnet, der beendet wurde, aber trotzdem noch in der Prozesstabelle des
Betriebssystems auftaucht und auch geringfügig Systemressourcen belegt. Zombie-Prozesse richten selbst
keinen Schaden an, können aber auf Fehlfunktionen hinweisen.
F S UID
PID
PPID
C PRI NI ADDR SZ WCHAN
0 S root 15344 14679 0 80
1 Z root 15345 15344 0 80
4 R root 15350 15289 0 80
0
0
0
-
STIME TTY
TIME
454 hrtime 16:24 pts/0 00:00:00 ./ynlahd
0 exit
16:24 pts/0 00:00:00 [ynlahd]<defunct>
1253 16:25 pts/1 00:00:00 ps -elf
PROCESS STATE CODES:
Here are the different values that the s, stat and state output specifiers
(header "STAT" or "S") will display to describe the state of a process:
D
R
S
T
W
X
Z
CMD
uninterruptible sleep (usually IO)
running or runnable (on run queue)
interruptible sleep (waiting for an event to complete)
stopped, either by a job control signal or because it is being traced.
paging (not valid since the 2.6.xx kernel)
dead (should never be seen)
defunct ("zombie") process, terminated but not reaped by its parent.
Aufgabe 3
Aufgabe 3
Zombie-Prozess
Was müsste im "Father"-Prozess wie verändert werden damit das Programm korrekt abläuft?
#include
#include
#include
#include
<stdlib.h>
<unistd.h>
<stdio.h>
<wait.h>
int main ()
{
if (fork()) { //Father process
printf("Father waits\n");
wait(0)
//-> sleep(60) → wait(0) oder waitpid(pid_t)
printf("Father stops waiting\n");
}
else { //Son process
printf("Son starts\n");
int i=0;
for(i=0;i<=10;i++) printf("Son counts %d\n",i);
printf("Son exits\n");
exit (1);
}
return 0;
}

Documentos relacionados