Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
1
Système d’Exploitation
IUT Belfort-Montbéliard 1ère année Système d’Exploitation Création/exécution de processus S. Domas
2
Définitions (1) S. Domas Le principe de processus est quasi indissociable de deux principes : la mémoire virtuelle et le mode d’exécution du processeur. La mémoire virtuelle permet de donner un espace mémoire propre à chaque processus. Dans une architecture 32 bits, cet espace virtuel fait 4Go et est découpé en pages mémoire (généralement de 4Ko). Un processus utilise une petite partie de cet espace virtuel. Par exemple, un processus de 10Mo utilise 2500 pages, répertoriées dans une table des pages associée au processus.
3
Définitions (2) S. Domas Le mode d’exécution du processeur est soit privilégié, soit non privilégié. On parle aussi respectivement de mode utilisateur et mode noyau. Quand le processeur est en mode utilisateur, il considère que toutes les adresses qu’il manipule sont virtuelles. Quand il est en mode noyau, il considère qu’il manipule directement la mémoire physique (comme sous DOS). Au gré de l’exécution des processus, le processeur va passer d’un mode à l’autre (par exemple sur une entrée/sortie).
4
S. Domas Définitions (3) Bien entendu, en mode utilisateur, le processeur doit quand même utiliser la mémoire physique malgré un adressage virtuel. Cette correspondance est faite par la Memory Management Unit (MMU), qui utilise pour ce faire la table des pages et des registres spéciaux. Pour simplifier, on dit souvent qu’un bout de code est en mémoire physique ou virtuelle selon son mode d’exécution. Par exemple, un code utilisateur est toujours en mémoire virtuelle alors qu’un pilote de périphérique est toujours en mémoire physique.
5
S. Domas Définitions (4) Quand un code utilisateur doit faire une entrée/sortie, il demande au système (= appel système) d’exécuter une fonction d’un pilote de périphérique. Un appel système permet donc de passer en mode noyau et ainsi d’accéder à toutes les fonctions et structures spéciales que maintient le système. Quand l’appel système est terminé, le processeur bascule de nouveau en mode utilisateur. Ce mécanisme assure l’intégrité du système en interdisant à un processus d’accéder directement au noyau.
6
S. Domas Définitions (5) Par extension, on appelle processus un programme chargé en mémoire virtuelle dans un état donné. Formellement, un processus est l'association d'un espace utilisateur et de structures système. Pour que le noyau du système d’exploitation garde une trace des processus existants, ces deux éléments sont référencés par un bloc de contrôle de processus.
7
Définitions (6) S. Domas L'espace utilisateur contient des segments de code et de données. Cette répartition en segments mémoire permet de contrôler et limiter les accès du processus à la mémoire. Par exemple, le segment de code est en lecture seule. Le code ne peut donc pas s’automodifier. La pile, le tas (allocation dynamique), les données statiques sont tous stockés dans des segments différents, qui peuvent éventuellement grandir. Accéder en dehors d’un segment provoque une erreur (= segmentation fault)
8
Définitions (7) S. Domas Parmi les structures système, il y a la structure utilisateur qui contient toutes les informations essentielles à la vie du processus lorsqu'il est en mémoire, notamment : une copie des registres, les identifiants utilisateur et groupe, le répertoire courant, la table des descripteurs.
9
Définitions (8) S. Domas Le bloc de contrôle de processus contient les informations essentielles pour permuter (= swap) le processus, notamment : un identifiant unique, un pointeur vers la table des pages ou une adresse sur un périphérique, des informations pour l'ordonnancement (priorité, longévité, ...) Les blocs de contrôle sont stockés dans une liste doublement chaînée, contenant également des pointeurs vers le bloc du processus père, du plus récent fils, etc.
10
Création d'un processus en C
S. Domas La création d'un processus se fait toujours à partir d'un processus existant (sauf le processus 0). En C, il existe principalement 3 appels pour créer un nouveau processus : fork(), vfork(), clone(). Suivant l'appel, le processus fils partage plus ou moins de choses avec son père en mémoire.
11
Création d'un processus en C: fork()
S. Domas L'appel à fork() crée un nouveau processus en créant un nouvel espace utilisateur, de nouvelles structures système et un nouveau bloc de contrôle. Le processus appelant fork() est dit "père" et le nouveau "fils". L'espace utilisateur du fils est rempli avec une copie de celui du père. De même, les structures systèmes sont copiées dans le processus fils. C'est pourquoi un fils hérite d'une copie de la table des descripteurs de son père.
12
Création d'un processus en C : fork()
S. Domas Comme le père et le fils ont une copie identique des données, donc de la pile, ils ont la même adresse de retour après le fork(). C'est pourquoi le père et le fils "continuent" leur exécution à la même instruction : celle qui suit le fork(). Seule différence : fork() renvoie 0 chez le fils et l'identifiant du fils chez le père. Les données étant copiées, toute modification dans le père n'a aucune influence dans le fils.
13
Création d'un processus en C : fork()
S. Domas Exemple : accès à une même variable. ... int pid, a; pid = fork(); if (pid > 0) { a = 5; printf("je suis le père, a = %d\n",a); } else if (pid == 0) { a = 10; printf("je suis le fils, a = %d\n",a); else { perror("pb création processus"); exit(1); le père et le fils reprennent à cette instruction après le fork(), avec des valeurs différentes de pid. affiche 5 affiche 10
14
Création d'un processus en C : fork()
S. Domas Exemple : accès au même descripteur. ... int pid, fd; char *msgp,*msgf; msgp = "je suis le pere"; msgf = "je suis le fils"; fd = open("toto", O_WRONLY | O_CREATE, S_IRWXU); pid = fork(); if (pid == 0) { write( fd, msgf, strlen(msgf)); } else if (pid > 0) { write( fd, msgp, strlen(msgp)); else { perror("pb création processus"); exit(1);
15
Création d'un processus en C : clone()
S. Domas L'appel à clone() permet de créer un fils qui partage l'espace utilisateur avec son père. Les paramètres de clone() sont un tampon qui va servir de pile "privée" au fils et l'adresse d'une fonction que va exécuter le fils. La pile "privée" est nécessaire pour que le père continue normalement son exécution. Contrairement à fork() et vfork(), le père et le fils ne reprennent pas l'exécution à la même instruction. clone() est souvent utilisé pour créer des threads.
16
Exécution d'un code en C : exec()
S. Domas L'appel à exec() permet de remplacer l'espace utilisateur d'un processus avec un autre segment de code et de données. C'est le recouvrement d'exécution. Cela revient en gros à exécuter un nouveau programme dans le processus. Les structures système sont inchangées donc le nouveau programme conserve, entre autre, la même table de descripteurs, ce qui est pratique lorsque l'on utilise des redirections. exec se traduit en C par une famille de fonctions : execv(), execvp(), execlp(), ...
17
Exécution d'un code en C : exec
S. Domas execlp() prend en premier paramètre le nom de l'exécutable et ensuite un nombre de paramètres variable correspondant aux arguments du programme. Par exemple : execlp ( "grep", "grep" , "truc" , "toto", (char *)NULL); execvp() prend en paramètre le nom de l'exécutable puis un tableau de chaînes de caractères représentant les arguments du programme. Par exemple : char *arg[3]; arg[0] = "ls"; arg[1] = "-al"; arg[2] = NULL; execvp(arg[0], arg);
18
Exécution d'un code en C : execlp()
S. Domas Exemple : ... int ret; ret = execlp ( "ls", "ls", "-al", (char *)NULL); if (ret < 0) { perror("pb de recouvrement"); exit(1); } else { printf("tout est ok\n"); ce message ne sera jamais affiché : si exec marche, ces instructions seront recouvertes par un autre code.
19
Fonctions C utiles S. Domas getpid() renvoie l'identifiant du processus courant et getppid() l'identifiant de son père. wait() permet au processus père d'attendre la fin de l'un de ces processus fils. wait() renvoie le pid du fils mort. exit() prend en paramètre un entier. Il permet de terminer l'exécution du code et du processus, notamment en fermant tous les descripteurs de fichiers encore ouverts. sleep() permet de mettre en attente un processus.
20
Exemple complet en C mettre un nom de commande à la place des ...
S. Domas mettre un nom de commande à la place des ... char *cmd = "...."; int pid, ret, status; pid = fork(); if (pid > 0) { printf("je suis le père %d et mon fils est %d\n",getpid(), pid); ret = wait(&status); printf("mon fils %d se termine par exit(%d)\n",ret,WEXITSTATUS(status)); exit(0); } else if (pid == 0) { printf("je suis le fils %d et mon père est %d\n",getpid(), getppid() ); execlp(cmd, cmd, (char *)NULL); exit(2); else { perror("pb création processus"); exit(1); cette ligne n'est exécutée que si execlp n'a pas marché, notamment si cmd n'existe pas.
21
Création d'un thread en Java
S. Domas En Java, il n’est pas possible de créer un processus « lourd » comme en C. On crée des threads, également appelés « processus légers ». L’avantage (et parfois l’inconvénient) des threads est qu’ils partagent tous le même espace mémoire, contrairement aux processus lourd qui ont chacun leur propre espace. Plusieurs threads peuvent donc avoir accès au même objet et peuvent le modifier, ce qui peut poser des problèmes de cohérence des données.
22
Création d'un thread en Java
S. Domas La méthode la plus simple pour créer un thread est d’hériter de la classe Thread. Les objets que le thread doit partager avec d’autres threads doivent être donnés au constructeur. Il faut également définir une méthode run(), qui sert de point d’entrée d’exécution, comme main() pour le programme principal. Pour lancer un thread, il faut le créer avec new puis appeler la méthode start() sur l’objet ainsi créer.
23
Création d'un thread : exemple
S. Domas public class MonThread extends Thread { Date date; public MonThread (Date date) { this.date = date; } public void run() { System.out.println ("thread started ! "); System.out.println ("date : " + date.toString()); …
24
Création d'un thread : exemple
S. Domas public class ExempleThread { public static void main (String args[]) { MonThread t1,t2; Date date = new Date(); t1 = new MonThread (date); t1.start(); t2.start(); }
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.