Université Pierre et Marie Curie

Systèmes d'exploitation des ordinateurs

Chapitre 1. Les systèmes d'exploitation
Chapitre 2. Mécanismes d'exécution et de communication
2.1. Notions sur les procédures
2.2. Notions sur les interruptions
2.3. Programmation des entrées-sorties
2.4. Les processus sous Unix
Chapitre 3. Gestion des activités parallèles
Chapitre 4. Gestion des fichiers
Chapitre 5. Partage des ressources
Chapitre 6. Au-dessus du système d'exploitation
Chapitre 7. Notions sur les communications
Chapitre 8. Notions sur la sécurité
Bibliographie
Chapitre 9. Exercices et TPs
Examens
Page d'accueilTable des matièresNiveau supérieurPage précédenteBas de la pagePage suivante

2.1. Notions sur les procédures

Notions sur les processus

On appelle activité ou processus un programme en cours d'exécution. Nous n'envisageons pas le cas où il   s'exécute sur plusieurs processeurs simultanément. Le processus se déroule de façon séquentielle: les instructions qui le composent sont chargées dans le processeur puis exécutées les une après les autres. Son état d'avancement est observable en un ensemble de points discrets avant ou après l'exécution d'une instruction. Un processus n'est pas observable pendant le temps d'exécution d'une instruction dans le processeur.

Le programme est lui-même constitué d'un ensemble de procédures. Une procédure est un ensemble logique qui se différentie essentiellement d'un programme par son mode de fonctionnement : elle n'est pas autonome, elle est elle-même appelée par une autre procédure et communique avec elle au moyen d'une liste d'arguments. Un programme est donc constitué d'un ensemble de procédures et la principale enclenche les appels à toutes les autres.

L'ensemble des procédures qui sont employées dans un processus est placé dans des zones d'adresses contiguës appelées segments. Le segment programme correspond à la partie du code qui contient les instructions. Il ne change jamais pendant toute la durée de l'activité puisque, par définition, un programme ne peut pas être modifié en cours de fonctionnement. Les données, c'est à dire l'ensemble des variables du programme manipulées en cours d'exécution, est rangé dans le segment de données. Le segment de données évolue sans cesse au fur et à mesure de l'exécution des instructions puisque les valeurs des variables changent. La connaissance du segment de données ainsi que d'autres informations définissent l'état du processus à tout instant dans la mémoire. A un instant donné, l'état du processeur est identifié par le contenu de l'ensemble de ses registres programmables, c'est à dire de ceux où l'on charge des informations en provenance de la mémoire et d'autres qui contiennent les résultats d'opérations correspondant au programme, ainsi que par certains  à usage purement interne. La connaissance de l'état du processus et de celui du processeur est indispensable pour décrire entièrement l'avancement du processus.

Contexte d'un processus

Examinons le contexte des échanges entre les procédures constitutives d'un processus. Considérons deux procédures P et Q. P déclenche l'exécution de Q. On peut décomposer le mécanisme de leurs échanges de la façon suivante :

  1. Préparation par P de la liste {lp} des paramètres à transmettre à Q.sauvegarde du contexte de P qui devra être retrouvé, après la fin de l'exécution de Q pour pouvoir continuer l'exécution de P. Ce contexte est constitué de l'ensemble des informations nécessaires à la description de l'activité de P dans l'état où elle était au moment où on l'a interrompue pour pouvoir exécuter Q. Il comprend les informations sur l'état de la mémoire: adresse des segments code et données, valeur du compteur ordinal qui pointe sur l'instruction en cours d'exécution ...remplacement du contexte de P par celui de Q.
  2. Exécution de Q

Au retour, lorsque Q est terminée, le mécanisme est presque symétrique: cependant le contexte de Q n'est pas sauvegardé puisque Q a terminé son existence :

  1. Préparation par Q de la liste {lq} des paramètres transmis par Q à P.restauration du contexte de P
  2. Exécution de la suite des instructions de P.

On notera que les données internes à Q sont perdues. Ceci signifie que si Q est appelé une seconde fois toutes les données internes à cette procédure seront réinitialisées. Il n'en est pas de même pour P dont les segments continuent à évoluer à chaque déchargement-chargement et gardent mémoire des actions antérieures. On dit que les données de Q sont de type automatique. On peut imaginer un mode de fonctionnement plus symétrique où le contexte de Q est sauvegardé à chaque retour vers P. On parle alors de fonctionnement en coroutines. Dans ce cas il est indispensable de préserver les données de Q en fin d'exécution de la procédure. Leurs valeurs peuvent être préservées. Il s'agit de données de type statique.

Etudions maintenant le mécanisme de changement de contexte. Il doit:

  1. sauvegarder tous les éléments nécessaires au fonctionnement de P après l'appel à Q.
  2. transmettre les paramètres de P à Q.
  3. gérer les zones de travail propres à chaque procédure. Il existe différentes méthodes pour réaliser ce mécanisme. Nous nous limiterons à un exemple basé sur l'usage d'une pile où les paramètres sont transmis par valeur comme en langage C.

A chaque appel de Q une structure, correspondant aux données qu'il faut lui transmettre, est crée. L'ensemble des valeurs de cette structure est stocké au sommet d'une pile. Au retour de Q vers P cette structure est supprimée. Deux pointeurs sur la base et le sommet de la pile sont mémorisées. Ce mécanisme permet un appel récursif à Q puisqu'il suffit d'empiler une nouvelle structure à chaque appel. En retour de chaque appel on récupère la dernière structure appelée. La seule limitation pratique est la taille de la pile prévue dans le mécanisme de débranchement. Celle-ci est souvent un paramètre du compilateur.


état d'une pile
     figure 2.1: Etat d'une pile      

Notons qu'il suffit de connaître les valeurs des pointeurs sommet et base pour pouvoir lire tous les éléments de la structure si la première donnée indique le nombre d'éléments.Parmi les éléments de l'environnement qu'il faut sauvegarder on notera :* l'adresse de retour de la procédure P, c'est à dire l'adresse de la prochaine instruction de P à exécuter :

  • l'adresse de la base du contexte (fig.2.1).
  • les paramètres: n+1 emplacements pour les n paramètres transmis à Q. Le premier élément de la structure indique le nombre n de paramètres.
  • les variables locales et l'espace de travail de P c'est à dire l'ensemble des informations indispensables au rétablissement de son fonctionnement au retour.

Dans le mécanisme de coroutine il faut imaginer un dispositif différent pour préserver également le contexte de Q, par exemple deux piles distinctes pour l'appel et le retour. Il ne faut pas oublier que les coroutines peuvent elles-mêmes inclure des procédures.

Le contexte d'un processus comprend donc un ensemble de paramètres regroupés dans les segments de la procédure en cours d'exécution (code et données) et la région d'environnement courant où sont rangés tous les éléments que nous venons d'évoquer. Cette description est incomplète mais suffisante pour notre propos.

Contexte du processeur

Plusieurs programmes coexistent simultanément dans la mémoire de l'ordinateur. Cependant celui-ci ne peut exécuter qu'une instruction à la fois. Il est donc réservé à l'usage d'un seul processus. Il ne suffit donc pas, pour décrire l'état du système à un instant donné, de connaître le contexte de chaque processus. Il faut aussi examiner celui du processeur. Cet état est décrit par:

  • le contenu des registres adressables
  • le contenu des registres spécialisés.

Ils sont regroupés sous le vocable mot d'état ou PSW (program status word) en anglais et définissent le contexte du processeur pour le processus en cours d'exécution. Notons qu'il faut également disposer d'informations sur la localisation en mémoire du   processus suivant à activer.

Le mot d'état comprend des informations sur :

  • l'état d'exécution: le processeur est actif ou en attente d'entrées-sorties (E/S). Nous verrons au chapitre III les mécanismes qui permettent de basculer d'attente en actif et réciproquement. La transition actif-attente se fait par une instruction spéciale.
  • le mode de fonctionnement. En mode : maître des instructions privilégiées sont accessibles. Elles sont interdites en mode esclave pour des raisons de sécurité. D'autres modes peuvent exister comme le mode trace (ou debug), utile pour débogguer un fonctionnement.
  • le masque d'interruption qui sera décrit au paragraphe suivant.
  • le contexte accessible en mémoire: adresse des tables de segments du processus en cours et du suivant
  • le déroulement du processus en cours, notamment le compteur ordinal qui contient l'adresse de l'instruction qui est exécutée.

La description complète de l'activité de l'ordinateur suppose connu les contextes des différentes activités présentes en mémoire ainsi que le contexte du processeur. Changer d'activité demande donc de sauvegarder les contextes du processeur et de l'activité en cours puis de les remplacer par ceux correspondant à l'activité qui va devenir active. Ces changements sont déclenchés par des interruptions.

Processus et threads

Un des rôles du système d'exploitation est d'assurer l'enchaînement des activités de plusieurs processus. Le passage de l'un à l'autre peut être décrit exactement comme l'enchaînement de deux procédures (fig. 2.1). Lorsque le processus P est arrêté il faut sauvegarder, à un emplacement prévu en mémoire,  son mot d'état ainsi que le contexte du processeur puis charger le mot d'état et le contexte du processeur correspondant au nouveau processus Q. Les informations relatives à deux processus sont complètement distinctes donc doivent être séparées et les mots d'état, les segments de code et de données des différents processus chargés dans la mémoire et susceptibles d'être actifs sont rangés à des adresses distinctes. Le système d'exploitation doit s'assurer qu'aucun processus ne va chercher à lire ou écrire dans une zone réservée à un autre. Ceci n'est pas toujours vrai : certains systèmes n'ont pas prévu de protections, ce qui peut être très ennuyeux et fragiliser le fonctionnement de l'ordinateur. Si le processus Q modifie intempestivement les données du processus P, il y a fort à parier que celui-ci ne pourra plus s'exécuter correctement ! L'ordinateur a de fortes chances de s'arrêter très brutalement.

Dans certains cas on peut vouloir partager certaines informations. Imaginons, par exemple, deux processus qui exécutent le même code avec deux jeux de données différents. Il est inutile de copier deux fois le segment de code en mémoire puisque cela revient à dupliquer deux fois la même image. La connaissance du mot d'état et du contexte du processeur relatifs à chaque processus suffisent pour assurer leur fonctionnement. Par contre le segment de données doit absolument être dupliqué puisqu'il n'existe aucune raison pour qu'ils soient identiques : cela signifierait que les deux processus font rigoureusement la même chose, au même instant, ce qui présenterait peu d'intérêt.

Depuis quelques années est apparue une notion nouvelle : celle de thread ou sous-processus.  Chaque thread possède son propre mot d'état, son propre contexte du processeur mais partage le même segment de code et de données que le processus. Cette notion ne présente d'intérêt que pour les machines à plusieurs processeurs. Si on décompose le processus en plusieurs threads, on peut confier leur exécution à chaque processeur. Comme les threads partagent le même segment de données il faut faire très attention, lorsqu'on les programme, pour éviter tout conflit et incohérence dans leur exécution.


Copyright Yves Epelboin, université P.M. Curie, 2000, MAJ 4 avril, 2005

Page d'accueilTable des matièresNiveau supérieurPage précédenteHaut de la pagePage suivante