Cours n°3 :
Processus

Réseau et Prog. Bas Niveau
Victor Poupet

Parallélisme

Les OS modernes sont tous capables d'exécuter plusieurs tâches en parallèle

Cycle d'un processus

cycle d'un processus

Les processus ont 5 états possibles d'exécution :

Bloc de contrôle

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 :

Changement de processus

changement de processus

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.

Anatomie d'un processus

La mémoire occupée par un processus est divisée en plusieurs sections :

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

size

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ées
  • bss correspondant aux variables globales ou statiques non initialisées ou initialisées à 0 (qui ne prennent donc pas de place dans l'exécutable)

text

La section text de la mémoire contient la séquence d'instructions à exécuter

Limites

$ 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.

Allocation dynamique

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

pile

La pile d'exécution est une structure LIFO (last in, first out)

  • divisée en blocs (frames) correspondant aux fonctions en cours
  • 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
  • lorsqu'une fonction termine, son bloc est supprimé de la pile et la fonction qui l'a appelée reprend son exécution

Pour chaque fonction en cours d'exécution, la pile contient :

  • l'adresse de retour qui correspond à l'instruction où reprendre l'exécution de la fonction précédente lorsque la fonction courante termine
  • les variables locales de la fonction
  • les arguments passés à la fonction
  • environnement à restaurer lorsque la fonction termine (privilèges, états de certains registres, etc.)

Lorsque la fonction termine, le résultat est placé sur la pile pour être traité par la fonction précédente.

PileTas

Virtualisation

mémoire virtuelle

Les processus n'ont pas directement accès aux différentes mémoires physiques