forked from IUTInfoMontp-M2101/cours
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cours03.html
272 lines (269 loc) · 12 KB
/
cours03.html
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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Cours n°3 : Processus</title>
<link rel="stylesheet" href="https://vpoupet.github.io/myriad/slides/slides.css">
<link rel="stylesheet" href="https://vpoupet.github.io/myriad/slides/themes/myriad/myriad.css">
<link rel="stylesheet" href="highlight.css">
</head>
<body>
<section class="title">
<h1>Cours n°3 :<br>Processus</h1>
<div class="context">M2101 - Architecture et programmation bas niveau</div>
<div class="author">Victor Poupet</div>
<time>2019-02-25</time>
</section>
<section class="single">
<h1>Parallélisme</h1>
<p>Les OS modernes sont tous capables d'exécuter plusieurs tâches en parallèle</p>
<ul>
<li>chaque tâche est réalisée par un <em>processus</em></li>
<li>en réalité un processeur ne peut exécuter qu'un seul processus à la fois à un instant donné</li>
<li>
pour les faire avancer en parallèle, le processeur alloue de petits intervalles de temps à chaque processus, en alternance (ordonnancement)</li>
</ul>
</section>
<section class="split">
<h1>Cycle d'un processus</h1>
<div class="side"><img src="cours03/cours03-cycle.svg" style="width: 100%" alt="cycle d'un processus"></div>
<div class="side">
<p>Les processus ont 5 états possibles d'exécution :</p>
<ul>
<li><strong>Nouveau :</strong> en cours de création</li>
<li>
<strong>Prêt :</strong> toutes les ressources nécessaires sont disponibles mais pas actuellement exécuté par le CPU</li>
<li><strong>Exécution :</strong> en cours d'exécution par le CPU</li>
<li>
<strong>En attente :</strong> ne peut pas poursuivre son exécution (attente clavier, fichier, message d'un autre processus, etc.)</li>
<li><strong>Terminé :</strong> l'exécution est finie</li>
</ul>
</div>
</section>
<section class="single">
<h1>Bloc de contrôle</h1>
<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 :</p>
<ul>
<li>Identification</li>
<ul>
<li>identifiant du processus (PID)</li>
<li>identifiant du processus parent (PPID)</li>
<li>identifiant de l'utilisateur et du groupe exécutant le processus (UID et GID)</li>
</ul>
<li>État du processeur</li>
<ul>
<li>registres</li>
<li>pointeurs de pile et exécution</li>
</ul>
<li>Contrôle du processus</li>
<ul>
<li>état d'exécution (prêt, suspendu, etc.)</li>
<li>descripteurs de fichiers ouverts</li>
<li>privilèges</li>
<li>comptabilité (temps CPU, date d'exécution, <em>etc.</em>)</li>
</ul>
</ul>
</section>
<section class="split">
<h1>Changement de processus</h1>
<div class="side">
<div class="center"><img src="cours03/cours03-switch.svg" style="width: 70%" alt="changement de processus"></div>
</div>
<div class="side">
<p>Pour changer le processus en cours d'exécution, le processeur doit :</p>
<ul>
<li>sauvegarder le PCB du processus en cours</li>
<li>charger le PCB du nouveau processus</li>
<li>reprendre l'exécution du nouveau processus</li>
</ul>
<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.</p>
</div>
</section>
<section class="single">
<h1>Anatomie d'un processus</h1>
<p>La mémoire occupée par un processus est divisée en plusieurs sections :</p>
<ul class="skip">
<li>une section <code>text</code> contenant les instructions (en langage machine) à exécuter par le processus</li>
<li>
une section <code>data</code> contenant les variables globales et statiques, allouées avant d'exécuter la fonction <code>main</code></li>
<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>
<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</li>
</ul>
<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</p>
</section>
<section class="split">
<h1>size</h1>
<div class="side">
<pre><code class="cpp">int tab[5000];
int tab2[1000] = {1};
int main() {
int tab2[20000];
return 0;
}</code></pre>
<hr>
<pre><code>$ size a.out
text data bss dec hex filename
1072 4276 20032 25380 6324 a.out</code></pre>
</div>
<div class="side">
<div class="only" data-step="0">
<p class="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>
<p>La section <code>data</code> d'un exécutable est divisée en deux parties :</p>
<ul>
<li><code>data</code> correspondant aux variables globales ou statiques initialisées</li>
<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)</li>
</ul>
</div>
<ul class="only" data-step="1">
<li class="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>
<li>Les variables globales ne peuvent pas avoir une taille variable (définie à l'exécution)</li>
</ul>
</div>
</section>
<section class="single">
<h1>text</h1>
<p class="skip">La section <code>text</code> de la mémoire contient la séquence d'instructions à exécuter</p>
<ul>
<li>Chargée au démarrage du programme et protégée en écriture</li>
<li>Un registre du processeur contient l'adresse de l'instruction en cours (<em>program counter</em> ou PC)</li>
</ul>
</section>
<section class="split">
<h1>Limites</h1>
<div class="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</code></pre>
</div>
<div class="side">
<p>
La fonction <code>ulimit</code> permet d'obtenir les limitations de taille imposées par le système d'exploitation.</p>
</div>
</section>
<section class="split">
<h1>Allocation dynamique</h1>
<div class="side">
<pre><code class="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);
}</code></pre>
</div>
<div class="side">
<p>Les fonctions de la famille <code>malloc</code> permettent de réserver de l'espace dynamiquement (dans le tas)</p>
<ul>
<li>La fonction renvoie un pointeur indiquant où se trouve le bloc de mémoire libéré</li>
</ul>
<p>
La fonction <code>free</code> permet de marquer la mémoire allouée par <code>malloc</code> comme étant libre</p>
<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></p>
</div>
</section>
<section class="split">
<h1>La pile</h1>
<div class="side">
<div class="center"><img src="cours03/cours03-pile.svg" style="width:70%" alt="pile"></div>
</div>
<div class="side">
<div class="only" data-step="0">
<p>La pile d'exécution est une structure LIFO (<em>last in, first out</em>)</p>
<ul>
<li>divisée en blocs (<em>frames</em>) correspondant aux fonctions en cours</li>
<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>
<li>
lorsqu'une fonction termine, son bloc est supprimé de la pile et la fonction qui l'a appelée reprend son exécution</li>
</ul>
</div>
<div class="only">
<p>Pour chaque fonction en cours d'exécution, la pile contient :</p>
<ul class="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>
<li>les variables locales de la fonction</li>
<li>les arguments passés à la fonction</li>
<li>
environnement à restaurer lorsque la fonction termine (privilèges, états de certains registres, etc.)</li>
</ul>
<p>
Lorsque la fonction termine, le résultat est placé sur la pile pour être traité par la fonction précédente.</p>
</div>
</div>
</section>
<section class="split">
<h1><span style="display: inline-block; text-align: center; width: 50%">Pile</span><span style="display: inline-block; text-align: center; width: 50%">Tas</span></h1>
<div class="side">
<ul>
<li>Fréquemment utilisée donc placée sur de la mémoire plus rapide</li>
<li>Variables libérées automatiquement</li>
<li>Connexe : ne se fragmente pas et facile d'accès</li>
<li>Gestion automatique de la portée des variables</li>
<li>Récursivité facile</li>
</ul>
</div>
<div class="side">
<ul>
<li>Espace illimité</li>
<li>Objets accessibles globalement</li>
<li>Doit être libéré explicitement</li>
<li>Objets peuvent être redimensionnés (<code>realloc</code>)</li>
</ul>
</div>
</section>
<section class="split">
<h1>Virtualisation</h1>
<div class="side"><img src="cours05/cours05-memoireVirtuelle.svg" style="width: 80%" alt="mémoire virtuelle"></div>
<div class="side">
<p>Les processus n'ont pas directement accès aux différentes mémoires physiques</p>
<ul>
<li>Ils disposent d'un espace de mémoire virtuelle</li>
<li>L'unité de gestion de mémoire (MMU) s'occupe de la correspondance</li>
<li>Permet d'isoler les processus</li>
<li>Masque les problèmes de fragmentation (le noyau s'en occupe)</li>
</ul>
</div>
</section>
<script src="highlight.pack.js"></script>
<script language="Javascript">
document.addEventListener('DOMContentLoaded', (event) => {
hljs.configure({
languages: [], // disable automatic language detection
});
document.querySelectorAll('code').forEach((block) => {
hljs.highlightBlock(block);
});
});
</script>
<script src="https://vpoupet.github.io/myriad/slides/slides.js"></script>
<script src="https://vpoupet.github.io/myriad/slides/themes/myriad/myriad.js"></script>
</body>
</html>