forked from IUTInfoMontp-M2101/cours
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcours03.pug
238 lines (214 loc) · 9.53 KB
/
cours03.pug
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
extends coursXX.pug
append preamble
- date = "2020-02-24";
- title = "Cours n°3 :<br>Processus";
block document
section.single
h1 Parallélisme
p Les OS modernes sont tous capables d'exécuter plusieurs tâches en parallèle
ul
li chaque tâche est réalisée par un <em>processus</em>
li en réalité un processeur ne peut exécuter qu'un seul processus à la fois à un instant donné
li pour les faire avancer en parallèle, le processeur alloue de petits intervalles de temps à chaque
| processus, en alternance (ordonnancement)
section.split
h1 Cycle d'un processus
.side
img(src="cours03/cours03-cycle.svg" style="width: 100%" alt="cycle d'un processus")
.side
p Les processus ont 5 états possibles d'exécution :
ul
li <strong>Nouveau :</strong> en cours de création
li <strong>Prêt :</strong> toutes les ressources nécessaires sont disponibles mais pas actuellement
| exécuté par le CPU
li <strong>Exécution :</strong> en cours d'exécution par le CPU
li <strong>En attente :</strong> ne peut pas poursuivre son exécution (attente clavier, fichier,
| message d'un autre processus, etc.)
li <strong>Terminé :</strong> l'exécution est finie
section.single
h1 Bloc de contrôle
p Le <em>bloc de contrôle</em> d'un processus (<em>process control bloc</em> ou PCB) est une structure de données
| utilisée par l'OS pour représenter ses informations :
ul
li Identification
ul
li identifiant du processus (PID)
li identifiant du processus parent (PPID)
li identifiant de l'utilisateur et du groupe exécutant le processus (UID et GID)
li État du processeur
ul
li registres
li pointeurs de pile et exécution
li Contrôle du processus
ul
li état d'exécution (prêt, suspendu, etc.)
li descripteurs de fichiers ouverts
li privilèges
li comptabilité (temps CPU, date d'exécution, <em>etc.</em>)
section.split
h1 Changement de processus
.side
.center
img(src="cours03/cours03-switch.svg" style="width: 70%" alt="changement de processus")
.side
p Pour changer le processus en cours d'exécution, le processeur doit :
ul
li sauvegarder le PCB du processus en cours
li charger le PCB du nouveau processus
li reprendre l'exécution du nouveau processus
p Ce transfert peut être réalisé après une interruption de l'exécution du premier processus à l'aide d'un appel
| système.
section.single
h1 Anatomie d'un processus
p La mémoire occupée par un processus est divisée en plusieurs sections :
ul.skip
li une section <code>text</code> contenant les instructions (en langage machine) à exécuter par le processus
li une section <code>data</code> contenant les variables globales et statiques, allouées avant d'exécuter la
| fonction <code>main</code>
li le tas (<em>heap</em>) utilisé pour l'allocation dynamique des variables, géré à l'aide de fonctions
| d'allocation (<code>malloc</code>, <code>free</code>, <em>etc.</em>)
li la pile (<em>stack</em>) utilisée pour stocker les variables locales, les arguments et la valeur de retour
| des procédures exécutées par le programme
p En plus de ces données, si le programme est interrompu, il faut également sauvegarder le compteur d'exécution
| ainsi que les valeurs contenues dans les registres du processeur
section.split
h1 size
.side
pre
code.cpp
| int tab[5000];
| int tab2[1000] = {1};
|
| int main() {
| int tab2[20000];
| return 0;
| }
hr
pre
code
| $ size a.out
| text data bss dec hex filename
| 1072 4276 20032 25380 6324 a.out
.side
.only(data-step=0)
p.skip La fonction <code>size</code> permet d'obtenir (entre autres) la taille des sections <code>text</code>
| et <code>data</code> correspondant à un exécutable
p La section <code>data</code> d'un exécutable est divisée en deux parties :
ul
li <code>data</code> correspondant aux variables globales ou statiques initialisées
li <code>bss</code> correspondant aux variables globales ou statiques non initialisées ou
| initialisées à 0 (qui ne prennent donc pas de place dans l'exécutable)
ul.only(data-step=1)
li.skip L'espace des variables globales est préparé par le compilateur, et réservé à la création du processus
| (la zone correspondant à <code>bss</code> est initialisée à 0)
li Les variables globales ne peuvent pas avoir une taille variable (définie à l'exécution)
section.single
h1 text
p.skip La section <code>text</code> de la mémoire contient la séquence d'instructions à exécuter
ul
li Chargée au démarrage du programme et protégée en écriture
li Un registre du processeur contient l'adresse de l'instruction en cours (<em>program counter</em> ou PC)
section.split
h1 Limites
.side
pre
code
| $ ulimit -a
|
| core file size (blocks, -c) 0
| <span class="highlight">data seg size (kbytes, -d) unlimited</span>
| file size (blocks, -f) unlimited
| max locked memory (kbytes, -l) unlimited
| <span class="highlight">max memory size (kbytes, -m) unlimited</span>
| <span class="highlight">open files (-n) 256</span>
| pipe size (512 bytes, -p) 1
| <span class="highlight">stack size (kbytes, -s) 8192</span>
| cpu time (seconds, -t) unlimited
| max user processes (-u) 709
| virtual memory (kbytes, -v) unlimited
.side
p La fonction <code>ulimit</code> permet d'obtenir les limitations de taille imposées par le système
| d'exploitation.
section.split
h1 Allocation dynamique
.side
pre
code.cpp
| int *fibo (int n) {
| int *t = malloc(sizeof(int)*(n+1));
| t[0] = 1;
| t[1] = 1;
| for (int i=2; i<=n; i++) {
| t[i] = t[i-1] + t[i-2];
| }
| return t;
| }
|
| int main() {
| int *t = fibo(100);
| int a = t[10];
| int b = t[100];
| free(t);
| printf("10: %d, 100: %d\n", a, b);
| }
.side
p Les fonctions de la famille <code>malloc</code> permettent de réserver de l'espace dynamiquement (dans le tas)
ul
li La fonction renvoie un pointeur indiquant où se trouve le bloc de mémoire libéré
p La fonction <code>free</code> permet de marquer la mémoire allouée par <code>malloc</code> comme étant
| libre
p La taille du tas disponible pour un processus n'est en général pas limitée, et c'est donc là que doivent
| être placés les objets de grande taille.</p>
section.split
h1 La pile
.side
.center
img(src="cours03/cours03-pile.svg" style="width:70%" alt="pile")
.side
.only(data-step="0")
p La pile d'exécution est une structure LIFO (<em>last in, first out</em>)
ul
li divisée en blocs (<em>frames</em>) correspondant aux fonctions en cours
li lorsqu'une sous-fonction est appelée, l'état de la fonction en cours est sauvegardé, et un nouveau
| bloc est placé sur la pile pour la sous-fonction
li lorsqu'une fonction termine, son bloc est supprimé de la pile et la fonction qui l'a appelée
| reprend son exécution
.only
p Pour chaque fonction en cours d'exécution, la pile contient :
ul.skip
li l'adresse de retour qui correspond à l'instruction où reprendre l'exécution de la fonction
| précédente lorsque la fonction courante termine
li les variables locales de la fonction
li les arguments passés à la fonction
li environnement à restaurer lorsque la fonction termine (privilèges, états de certains registres,
| etc.)
p Lorsque la fonction termine, le résultat est placé sur la pile pour être traité par la fonction
| précédente.
section.split
h1
span(style="display: inline-block; text-align: center; width: 50%") Pile
span(style="display: inline-block; text-align: center; width: 50%") Tas
.side
ul
li Fréquemment utilisée donc placée sur de la mémoire plus rapide
li Variables libérées automatiquement
li Connexe : ne se fragmente pas et facile d'accès
li Gestion automatique de la portée des variables
li Récursivité facile
.side
ul
li Espace illimité
li Objets accessibles globalement
li Doit être libéré explicitement
li Objets peuvent être redimensionnés (<code>realloc</code>)
section.split
h1 Virtualisation
.side
img(src="cours05/cours05-memoireVirtuelle.svg" style="width: 80%" alt="mémoire virtuelle")
.side
p Les processus n'ont pas directement accès aux différentes mémoires physiques
ul
li Ils disposent d'un espace de mémoire virtuelle
li L'unité de gestion de mémoire (MMU) s'occupe de la correspondance
li Permet d'isoler les processus
li Masque les problèmes de fragmentation (le noyau s'en occupe)