Système d exploitation Benjamin Bergougnoux LIMOS, Université Blaise Pascal 24 janvier 2017
> CM 1 > CM 2 > CM 3
Organisation 18h de CM 16h de TD, 2 groupes (A/B), début semaine pro, 16h de TP, 3 groupes (1/2/3), début semaine pro-pro.
Organisation 18h de CM 16h de TD, 2 groupes (A/B), début semaine pro, 16h de TP, 3 groupes (1/2/3), début semaine pro-pro. Évaluation Un partiel, Un contrôle en TD, Un contrôle en TP.
Organisation 18h de CM 16h de TD, 2 groupes (A/B), début semaine pro, 16h de TP, 3 groupes (1/2/3), début semaine pro-pro. Évaluation Un partiel, Un contrôle en TD, Un contrôle en TP. Note finale : max(partiel, moy(75%partiel + 12.5%TD + 12.5%TP))
Organisation Informations, Supports CM,TD,TP sur : http ://fc.isima.fr/ bergougn/ https ://coursenligne.clermont-universite.fr/ ENT Pédagogie Cours en ligne Nom du cours : L3_info-Système d Exploitation 2017 Clef : GANDALF FAQ
Conseils Comprendre = Temps + Concentration! Suivre le CM > Prendre des Notes > Végété Entraidez vous : révisez ensemble Posez des questions Soyez indépendants (prof incompétent = étudiant fort!)
WTF OS? Un OS (Operating System) c est Un truc qui rend l hardware facilement exploitable :
WTF OS? Un OS (Operating System) c est Un truc qui rend l hardware facilement exploitable : Donne aux développeurs une base (/bin) Rends les choses simples, uniformes et cohérente (/media) Se charge de 5 grands machins comme : Les fichiers Les processus La mémoire Les «E/S» Les utilisateurs
WTF OS? II Un OS (Operating System) ce n est pas : L interprète de commandes (logicielle système) L interface graphique Les utilitaires (cp, chmod, ls,...) Le BIOS
WTF OS? III Un OS (Operating System) c est : Une machine virtuelle Vue Uniforme des entrées/sorties Une mémoire virtuelle et partageable Gestions Fichiers et Répertoires Gestion droits d accès, sécurité et traitement d erreurs Gestions Processus (Ordonnancement, Communication,... ) Un gestionnaire de ressource Fonctionnement des Ressources Contrôle l accès aux Ressources Gestion des erreurs L évitement des conflits (ressource critique)
Pourquoi suivre cette UE? C est la BASE, le b.a.-ba, le cambouis primordial... C est votre ami : il gère vos programmes, Les problèmes rencontrés sont classiques, Il fait froid dehors, j ai vu de la lumière... Il y a des images
Types d OS Différents types d OS pour différents types de trucs à faire : Mono utilisateur Temps réel (Nucléaire, Chimie) : réactif Général (Linux, Windows, Android, Mac OS,...) Multi-tâches et Multi-utilisateurs
Mode Noyau / Utilisateur Mode Noyau (ou Kernel ou privilégié) Empire du système d exploitation Accès à tous les espaces mémoire Accès à toutes les instructions protégées Lecture/Écriture d un fichier des périphériques Accès au Réseaux Bref accès au hardware Accès aux droits d accès Super utilisateur Mode Utilisateur (ou non privilégié) Royaumes des programmes Processus ne peut accéder qu à son espace perso Grosse protection!
Accès au mode Noyau Appels Système Faire le schéma cool, Paramètre d un TRAP : Le numéro de la fonction système et les différents arguments de la fonction On appelle le gestionnaire d?exception trap handler Appel de la vraie fonction système Après calcul : Retour au trap Transmission de la valeur de retour et données Retour en mode utilisateur
Noix Shell : interface utilisateur Kernel : interface hardware/logiciel (noyau en allemand)
Types de noyau Type de noyau : Noyau Monolithiques D un bloc, absence de structure interne Une collection de procédures sans ordre Seule barrière de protection : Mode Noyeau / Mode utilisateur Différents types de procédures : Procédure principale Procédure de service Procédure utilitaire Populaire : Linux
Types de noyau
Types OS III Noyau Micro-kernel Noyau minimal Le reste du SE est en mode utilisateur Mac OS, Windows(récent) Hybride
WTF processus? Processus = une tâche d un programme = Royaume = Code + Données Statiques / Dynamiques Processus lourds : processus Tâche légère : thread Arborescence
WTF processus? Processus = une tâche d un programme = Royaume = Code + Données Statiques / Dynamiques Processus lourds : processus Tâche légère : thread Arborescence État d un processus Certaines infos sont à la charge du SE (compteur, liste fichiers ouverts,...) table des processus
Pas d enseignant en TP On va convertir certains CMs, TDs en TPs... À suivre
Previously on Operating System Un Système d Exploitation c est : Une machine virtuelle L hardware compliqué OS simple, uniforme et cohérent Gère les droits d accès, la sécurité et les traitements d erreurs Gère les processus : Ordonnancement et Communication (IPC) Un gestionnaire de ressource qui Gère le fonctionnement des ressources Lecture de disque, Réseaux, mémoire... Contrôle l accès aux Ressources : TRAP Gère les erreurs Permet l évitement des conflits : Sémaphores
Previously on Operating System Mode utilisateur : Mode par défaut des processus Accès uniquement à son espace perso
Previously on Operating System Mode utilisateur : Mode par défaut des processus Accès uniquement à son espace perso Mode Noyau Accès à tout l hardware (mémoire, réseaux, droits d accès...) Habité par les instructions protégées (kill, open, ls,...)
Previously on Operating System Apppel Système = Requête d un processus pour utiliser une instruction protégée 1. Processus appelle une fonction wrapper (glibc) Souvent éponyme 2. Fonction wrapper lance l appel système (syscall(int)) Copie des paramètres dans les bons registres 3. Interruption du processus : sauvegarde du contexte 4. Appel de l instruction protégée 5. Transfert des résultats et reprise du processus 6. Si erreur : retour < 0 et modification de errno
Gestion d erreur Si l appel système échoue alors il renvoie -1 ou NULL Il change la valeur de errno : un entier défini par <errno.h> Cet entier référence un type d erreur EACCES = Permission denied Afficher l erreur : perror
Gestion d erreur III /* perror example */ # include <stdio.h> int main () { FILE * pfile ; pfile = fopen (" unexist. ent ","rb"); if ( pfile == NULL ) perror (" The following error occurred "); else fclose ( pfile ); return 0; } The following error occurred : No such file or directory
Processus Processus = une tâche 1. Trois états : Prêt, Exécution et Bloqué 2. Bloc de contrôle de Processus : Pid État Compteur ordinal Allocation mémoire Fichier ouverts... Tout pour suspendre/reprendre le processus
Changement de contexte
Création de processus Les DÉMONS : Processus en background, associés à aucun terminal/login Démarrent au démarrage Attendent des événements Réalisent des tâches de manière périodiques Exemple : Cron pour chronos
Création de processus Tout le monde a un père sauf init (systemd) Tout processus peux créer/supprimer des processus fils Services POSIX pour la gestion de processus : pid_t fork() : création d un fils int execl(), int execlp(), int execvp(), int execle(), int execv() : Exécution d un programme pid_t wait(), pid_t waitpid : Attendre la fin d un processus void exit() : Finir l exécution d un processus pid_t getpid(), pid_t getppid() : Obtenir un pid system() : Lance une commande
Fork() Seul moyen de dupliquer un processus existant (Ou pas clone()) Créer une copie exacte du processus même (code), compteur,... Mais espace mémoire, pid, ppid différents! Valeur de retour de fork() : 0 pour le processus fils pid du fils pour le père Négative si échec # include < unistd.h> int fork ();
# include <sys / types.h> # include < unistd.h > # include < stdio.h > int main ( ){ int i; pid_t pid ; printf (" pid : %d, ppid : %d.\n", getpid (), getppid ()); pid = fork (); if(pid == -1) perror (" Fork fail :"); else if ( pid == 0 ){ printf (" pid : %d, ppid : %d.\n", getpid (), getppid ()); sleep (5) ; printf (" pid : %d, ppid : %d.\n", getpid (), getppid ()); } else return 0; return 0 ; }
Orphelins Si le processus père termine avant, le fils est orphelin, il est adopté! moi>./orphan pid : 7834, ppid : 4006. pid : 7835, ppid : 7834. moi> pid : 7835, ppid : 1635.
Wait(), waitpid() et exit() wait(int *status) : Attendre la mort d un fils waitpid(int pid, int *status, int options) : Attendre la mort du fils pid option : WNOHANG exit(int return_code) : termine l exécution et envoie statut statut : contient des infos sur la mort du fils <sys/wait.h> fournit des macros WEXITSTATUS(status) : return_code)
Processus Zombie Créer un zombie : int main ( ) { pid_t pid ; pid = fork (); if ( pid == 0 ) exit (0) ; // fils else sleep (10) ;// pere return 0; } 8874 pts/2 00 :00 :00 a.out 8875 pts/2 00 :00 :00 a.out <defunct>
Processus Zombie Bref un père qui n attends pas son fils Un processus zombie et orphelin est adopté puis attendu! while ( waitpid (-1, NULL, WNOHANG ))
Exec() Permet de changer l image d un processus int execv ( const char * path, char * const argv []) ; int main ( ){ execl ("/ bin /ls", "l", NULL ); perror (" Erreur execl "); return 1; }
Exec() Permet de changer l image d un processus int execv ( const char * path, char * const argv []) ; int main ( ){ execl ("/ bin /ls", "l", NULL ); perror (" Erreur execl "); return 1; } Equivalence : execlp("ls", "l", NULL) ;
Exec() Permet de changer l image d un processus int execv ( const char * path, char * const argv []) ; int main ( int argc, char * argv []) { char * args [] = {"ls", "-l", argv [1], NULL }; execv ("/ bin /ls", args ); perror (" Erreur execl "); return 1; }
Exec() Permet de changer l image d un processus int execv ( const char * path, char * const argv []) ; int main ( int argc, char * argv []) { char * args [] = {"ls", "-l", argv [1], NULL }; execv ("/ bin /ls", args ); perror (" Erreur execl "); return 1; } Équivalence : execvp("ls", args) ; À utiliser avec fork! Il y a aussi execle() voir man exec...
System() int main () { system ("ls -l /"); return 0; } Ça consiste en un fork() + exec() + wait() C est simple mais couteux : ça appel un shell Ça fait 2 fork in fact!
Les threads Un thread est un chemin d exécution d un processus Les threads sont inclus dans un processus
Les threads Un thread est un chemin d exécution d un processus Les threads sont inclus dans un processus Les threads d un même processus partagent les ressources du processus sont partagés entre ces threads Code exéc., mémoire, fichiers, périphériques... Chaque thread possède en plus : sa zone de données, sa pile d exécutions, ses registres et son compteur ordinal
Pourquoi? Pourquoi les threads? Rapide à créer : pas de contexte à créer Communication inter-thread super simple et rapide! Réactivité : un thread pour attendre l user les autres bossent Parallélisation d une tâche! Plus difficile à manier : Synchronisation et Crash
Création de thread Les fonctions de la bibliothèque pthread : int pthread_create( pthread_t * thread, pthread_attr_t * attr, ( taille de la pile, priorité,...) void *nomfonction, void *arg) ; Créer un thread qui exécute nomfonction(arg)
Création de thread Les fonctions de la bibliothèque pthread : int pthread_join(pthread_t *thid, void **valeur_de_retour) ; void pthread_exit(void *valeur_de_retour) ; int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) ; sert à établir l état de terminaison d un processus léger : PTHREAD_CREATE_DETACHED : le processus léger libérera ses ressources quand il terminera PTHREAD_CREATE_JOINABLE : le processus léger ne libérera pas ses ressources
Création de thread # include <stdio.h> # include < pthread.h> static void * task_a ( void * p_data ); static void * task_b ( void * p_data ); int main ( void ){ pthread_ t ta; pthread_ t tb; pthread_ create (& ta, NULL, task_a, NULL ); pthread_ create (& tb, NULL, task_b, NULL ); pthread_join (ta, NULL ); pthread_join (tb, NULL ); puts (" main end "); return 0; }
Communication inter-processus Différents moyens : Les Fichiers / variables Attention ressource critique Communication inter-thread Les signaux Aussi utilisé pour signaler des erreurs (Segmentation fault) Tubes sans nom (Anonymous pipe) Unidirectionnel, uniquement entre père et fils Tubes de communication nommés (Named pipe) Unidirectionnel, pas besoin de parenté
Fichiers / Variables communes Attention : fait de l exclusion mutuelle en écriture! P1 : movl $v,%eax # load v movw (%eax),%bx incw %bx # bx++; movw %bx, (%eax) # store v P2 : movl $v, %eax # load v movw %eax), %bx decw %bx # bx--; movw %bx, (%eax) # store v
Semaphore Edsger Dijkstra in 1962 or 1963 Un entier, deux opérations atomiques : P(rendre) V(rendre) Sur POSIX : int sem_init(sem_t *semaphore, int pshared, unsigned int valeur) Initialisation int sem_wait(sem_t * semaphore) ; Prendre, attente passive si 0 jeton, retourne 0 int sem_trywait(sem_t * semaphore) ; Prendre, retourne -1 si pas de jeton, 0 sinon int sem_post(sem_t * semaphore) ; int sem_getvalue(sem_t * semaphore, int * sval) ; int sem_destroy(sem_t * semaphore) ;
Semaphore sem_t mutex ; int main (){ sem_ init (& mutex, 0, 1);// Initialisation pour des threads... sem_ wait (& mutex );// accès en section critique... sem_ post (& mutex );// quitter section critique... }
Signaux Utiliser par l OS signaler des erreurs comme segmentation fault, buffer overflow,... L utilisateur/un programme peut aussi en envoyer int kill(pid_t pid, int signal) pid>0 : processus pid pid=0 : groupe de l émetteur pid=-1 : tous les processus (only for root) pid<0 : au groupe gid= pid signal SIGKILL, SIGTERM, SIGSTOP, SIGCONT, SIGINT...
Interpréter les Signaux