Les OS modernes sont tous capables d'exécuter plusieurs tâches en parallèle
Les processus ont 5 états possibles d'exécution :
Le bloc de contrôle d'un processus (process control bloc ou PCB) est une structure de données utilisée par l'OS pour représenter ses informations :
Pour changer le processus en cours d'exécution, le processeur doit :
Ce transfert peut être réalisé après une interruption de l'exécution du premier processus à l'aide d'un appel système.
La mémoire occupée par un processus est divisée en plusieurs sections :
text
contenant les instructions (en langage machine) à exécuter par le processusdata
contenant les variables globales et statiques, allouées avant d'exécuter la fonction main
malloc
, free
, etc.)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
int tab[5000];
int tab2[1000] = {1};
int main() {
int tab2[20000];
return 0;
}
$ size a.out
text data bss dec hex filename
1072 4276 20032 25380 6324 a.out
La fonction size
permet d'obtenir (entre autres) la taille des sections text
et data
correspondant à un exécutable
La section data
d'un exécutable est divisée en deux parties :
data
correspondant aux variables globales ou statiques initialiséesbss
correspondant aux variables globales ou statiques non initialisées ou initialisées à 0 (qui ne prennent donc pas de place dans l'exécutable)bss
est initialisée à 0)La section text
de la mémoire contient la séquence d'instructions à exécuter
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 256
pipe size (512 bytes, -p) 1
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 709
virtual memory (kbytes, -v) unlimited
La fonction ulimit
permet d'obtenir les limitations de taille imposées par le système d'exploitation.
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);
}
Les fonctions de la famille malloc
permettent de réserver de l'espace dynamiquement (dans le tas)
La fonction free
permet de marquer la mémoire allouée par malloc
comme étant libre
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.
La pile d'exécution est une structure LIFO (last in, first out)
Pour chaque fonction en cours d'exécution, la pile contient :
Lorsque la fonction termine, le résultat est placé sur la pile pour être traité par la fonction précédente.
realloc
)Les processus n'ont pas directement accès aux différentes mémoires physiques