La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Gestion des tâches.

Présentations similaires


Présentation au sujet: "Gestion des tâches."— Transcription de la présentation:

1 Gestion des tâches

2 Les tâches dans un environnement TR
La plupart des applications temps réel exigent une exécution parallèle de plusieurs activités utilisation optimale des ressources gain de temps quand c'est possible mais les exigences en termes de conception sont plus grandes Concepts présentés : définition états d'une tâche et ordonnancement opérations sur une tâche l'interface POSIX

3 Définition d'une tâche Un fil d'exécution indépendant qui peut entrer en compétition avec d'autres fils pour accéder à la CPU définition ''récursive'' utilisée pour optimiser la gestion des entrées/sorties une tâche est ordonnançable et est définie par un ensemble de paramètres contenus dans des structures de données nom identificateur priorité bloc de contrôle pile liste d'instructions (routine) TCB Stack Task Name/ID plus hautes priorités int MyTask() { while (1) } 130 plus basses priorités

4 États d'une tâche Sommeil appel système bloquant fin appel système
Interruptible(S) Non Interruptible (D) appel système bloquant fin appel système ou signal reçu Zombie (Z) fin de la tâche Inexistante Exécution (R) création Arrêt (T) signal SIGSTOP SIGCONT Inexistante lecture du code de terminaison le noyau gère les états des différentes tâches sous son contrôle l'ordonnanceur provoque les changements d'états et si nécessaire provoque un changement de contexte

5 Processus et Threads processus (process) : entité ordonnançable possédant son propre espace d'adressage les threads existent à l'intérieur d'un process (appartenant au noyau ou à l'utilisateur) et partagent l'espace d'adressage du process hôte. Ils sont ordonnançables indépendemment (le process hôte est un thread comme les autres) chaque thread possède son bloc de contrôle (TCB), ses registres et sa pile (stack) la création d'un process est plus lente et plus lourde en termes de consommation de ressources que celle d'un thread mais l'espace mémoire est beaucoup mieux protégé

6 Primitives pour la gestion des tâches
Fonctions à remplir création destruction gestion de l'ordonnancement suspendre reprendre retarder redémarrer modifier la priorité bloquer la préemption

7 Création des processes
fork pid_t fork(void) clonage d'un process un appel, mais deux retours... le process qui a appelé fork récupère le PID du nouveau process le process qui a été créé récupère 0 switch (pidFils=fork()) { case -1: perror("fork"); exit(2); break; case 0: process_fils(); break; default: process_pere(); break; }

8 Création des processes
exec remplace l'image exécutée par une autre execl(const char *file,const char *arg0,...,NULL); execv(const char *file,char *const argv[]); execle(const char *file,const char *arg0,...,NULL,char *const envp[]); execve(const char *file,char *const arg[],char *const envp[]); execlp(const char *file,const char *arg0,...,NULL); execvp(const char *file,char *const argv[]); execl prend une liste d'arguments terminée par NULL execv prend un vecteur de pointeurs d'arguments la terminaison en e indique qu'il y aura une 2ème liste ou vecteur passé pour préciser l'environnement (sous la forme key=value) la terminaison en p indique qu'il faut utiliser la variable d'environnement PATH pour localiser file le main de file est exécuté avec la liste d'arguments passée

9 Destruction des processes
exit et _exit termine le processus #include <stdlib.h> void exit(int status); void _exit(int status); la différence entre les deux fonctions tient dans la façon dont elles "nettoient" l'environnement (_exit ne fait pas appel aux fonctions enregistrées par atexit) elles ne retournent rien !

10 Destruction des processes
wait et waitpid attente de la fin du process fils par le père pid_t wait(int *status); pid_t waitpid(pid_t which,int *status,int options); int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options); tant que le parent n'a pas appelé wait, waitpid ou waitid, le fils terminé est un "zombie" (occupation de ressources) voir les pages man pour les options

11 utilitaires pid_t getpid()
retourne le PID du process déclaré dans <unistd.h> pid_t getppid() retourne le PID du process père déclaré dans <unistd.h>

12 utilitaires : obtenir de l'information
système de fichier proc pseudo-système utilisé comme interface entre les utilisateurs et des données relatives au noyau historiquement, prévu pour passer des informations relatives aux processes tournant dans le système monté généralement sur /proc facile à utiliser → usage étendu à d'autres informations le système sysfs introduit dans le noyau 2.6 est mieux organisé, mais un peu plus complexe à utiliser un répertoire /proc/pid est associé à chaque process contient plusieurs répertoires et fichiers le fichier /proc/pid/status contient plusieurs informations sur le process concerné peut être facilement accédé en lecture (cf TD)

13 Ordonnancement des processes
POSIX.4 définit 3 algorithmes SCHED_FIFO la priorité est le seul paramètre les tâches sont rangées dans des queues par niveau de priorité la 1ère tâche de la queue de plus haute priorité obtient la CPU elle la garde jusqu'à sa terminaison ou jusqu'à ce qu'elle soit bloquée quand elle redevient Prête, la tâche est mise en fin de queue SCHED_RR (Round Robin) comme FIFO, mais avec en plus un quantum de temps la tâche rend la CPU à l'expiration du quantum de temps SCHED_OTHER dépend de l'implémentation algorithme « temps partagé »

14 Ordonnancement des processes
depuis la version 3.14, Linux offre la politique SCHED_DEADLINE (non conforme POSIX.4) implémente les algorithmes EDF et CBS EDF bien connu CBS (Constant Bandwidth Server) développé par G. Buttazzo permet de servir des tâches apériodiques en optimisant la date d'échéance

15 Modifications de l'ordonnancement
#include <sched.h> sched_setscheduler, sched_getscheduler int sched_setscheduler(int pid, int policy, const struct sched_param *param) int sched_getscheduler(int pid, struct sched_param *param) modifie (ou obtient) les paramètres de l'ordonnanceur, y compris la politique sched_setparam, sched_getparam int sched_setparam(int pid, const struct sched_param *param) int sched_getparam(int pid, struct sched_param *param) modifie (ou obtient) les paramètres de l'ordonnanceur struct sched_param { int sched_priority; };

16 Modifications de l'ordonnancement
sched_get_priority_min, sched_get_priority_max int sched_get_priority_min(int policy); int sched_get_priority_max(int policy); sched_yield int sched_yield(void); relâche volontairement le processeur, sans se bloquer attention : ce n'est pas parce que un process de haute priorité relâche le processeur que les processes de priorité inférieure vont être exécutés !

17 Création des threads #include <pthread.h> les caractéristiques des threads (attributs) sont décrites dans une structure spéciale accédée par des fonctions dédiées initialisation aux valeurs par défaut : pthread_attr_init(pthread_attr_t *attr); libération des ressources liées aux attributs : pthread_attr_destroy(pthread_attr_t *attr);

18 Création des threads Modification des valeurs des attributs
pthread_attr_setstacksize pthread_attr_setstackaddr pthread_attr_setdetachstate PTHREAD_CREATE_DETACHED PTHREAD_CREATE_JOINABLE pthread_attr_setschedparam pthread_attr_setschedpolicy SCHED_FIFO SCHED_RR SCHED_OTHER pthread_attr_setinheritsched PTHREAD_EXPLICIT_SCHED PTHREAD_INHERITSCHED pthread_attr_setscope PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_PROCESS

19 Création des threads Lecture des valeurs courantes
pthread_attr_getstacksize pthread_attr_getstackaddr pthread_attr_getdetachstate pthread_attr_getschedparam pthread_attr_getschedpolicy pthread_attr_getinheritsched pthread_attr_getscope

20 Création des threads extensions (non portables) de Xenomai
pthread_attr_set/getfp_np utilisation d'un co-processeur pour le calcul en point flottant pthread_attr_set/getname_np nom donné au thread (pour /proc/xenomai/sched) pthread_attr_set/getaffinity_np établit l'affinité (utilisation préférentielle d'un des processeurs en environnement SMP)

21 Création des threads pthread_create pthread_self pthread_equal
crée un thread int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void * (*start_func)(void *), void *arg); pthread_self retourne le tid du thread appelant pthread_t pthread_self(void); pthread_equal compare les tid de 2 threads retourne 0 s'ils sont différents pthread_equal(pthread_t tid1, pthread_t tid2);

22 Création des threads pthread_join récupère le status de terminaison
appel bloquant : attend la terminaison d'un thread (attente de synchronisation sur la fin du thread) pthread_join (pthread_t tid,void **status); récupère le status de terminaison retourne immédiatement si le thread est déjà terminé le thread doit avoir été créé en mode joignable pthread_detach transforme un thread joignable en thread détaché int pthread_detach(pthread_t tid);

23 Destruction des threads
pthread_exit auto-destruction void pthread_exit(void *status); passe éventuellement le status de retour au thread en attente de synchronisation sur la fin

24 Destruction des threads
pthread_cancel demande de destruction d'un autre thread int pthread_cancel(pthread_t tid); L'effet de l'appel dépend de la politique adoptée par le thread visé : int pthread_setcancelstate(int state, int *ostate) int pthread_setcanceltype(int type, int *otype) état PTHREAD_CANCEL_DISABLE PTHREAD_CANCEL_ENABLE type PTHREAD_CANCEL_ASYNCHRONOUS destruction immédiate PTHEAD_CANCEL_DEFERRED destruction quand le thread atteint un point d'annulation : (appel à pthread_testcancel ou appel à une fonction bloquante)

25 Destruction des threads
Handlers de terminaison exécutés à l'appel de pthread_exit ou sur une annulation stockés dans une pile manipulée par void pthread_cleanup_push(void (*handler)(void *), void *arg); void pthread_cleanup_pop(int execute); exécutés en mode LIFO lors de la terminaison du thread (pthread_exit) si on retire un handler de la pile (pthread_cleanup_pop), il est exécuté seulement si l'argument passé par pthread_cleanup_pop vaut 1

26 threads et fork quand un thread exécute un fork, il va créer un nouveau process même image mémoire que le père mêmes ressources (descripteurs de fichiers, mutexes, etc...) mais le process fils n'a qu'un seul thread, qui est la réplique du thread du père qui a appelé le fork Attention à des situations parfois inextricables ! le process fils peut hériter de locks qui ont été pris par des threads du père n'existant pas dans le process fils l'espace mémoire du fils peut comporter des zones du heap qui ont été alloués à des threads n'existant pas dans le process fils utilisation de la fonction pthread_atfork pour aider à gérer ces difficultés

27 threads et fork int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)); installe dans 3 stacks différents des handlers qui seront exécutés au moment de l'appel à fork prepare sera exécuté par le père avant l'exécution du fork parent sera exécuté par le père au retour du fork child sera exécuté par le fils au retour du fork peut être applé plusieurs fois les handlers seront appelés en mode LIFO si on fait un appel à exec dans un process multithreadé, alors on détruit tous les autres threads et on démarre la nouvelle image dans son main

28 ordonnancement des threads
politique définie à la création par un attribut priorité politique (FIFO, Round Robin) visibilité "système" (seule visibilité supportée par Linux. La seule "utile" pour les applications de type temps réel) "process" dépend beaucoup de l'implémentation et de la configuration hardware (mono ou multi-processeur) pour l'élection d'un thread activable ou bloqué "priorité à la priorité" pour l'élection du thread la politique va déterminer la façon de rendre la CPU

29 ordonnancement des threads
pthread_setschedparam, pthread_getschedparam modification des paramètres de l'ordonnancement int pthread_setschedparam(pthread_t tid, int policy, const struct sched_param *param); int pthread_getschedparam(pthread_t tid, int *policy, struct sched_param *param); analogue aux primitives sched_xxx l'héritage de la politique d'ordonnancement du thread créateur se gère avec l'attribut setinheritsched

30 ordonnancement des threads
Ordonnancement des mutex mécanismes de changement des priorités en donnant au mutex une priorité que le thread courant récupérera (priority ceiling) ou en donnant au thread possédant le mutex la plus haute priorité des threads en attente du mutex (priority inheritance) plus de détails dans le cours sur les IPC

31 choix des processeurs (spécifique Linux)
sur des systèmes multiprocesseurs ou multicœurs, il est possible de choisir le (ou les) processeurs ou cœurs sur lequel la tâche va s 'exécuter spécifique de Linux (extension GNU) il faut définir la constante symbolique GNU_SOURCE avant l'include de sched.h : #define _GNU_SOURCE #include <sched.h> … consultation du processeur utilisé int sched_getcpu(void); vous pouvez afficher la liste des cœurs disponibles sur votre machine à l'aide de la commande taskset : taskset -c -p $$

32 choix des processeurs (spécifique Linux)
choix des processeurs autorisés un ensemble de processeurs utilise des variables de type cpu_set_t manipulées par des macros CPU_ZERO (cpu_set_t * ensemble); CPU_SET (int cpu, cpu_set_t * ensemble); CPU_CLR (int cpu, cpu_set_t * ensemble); CPU_ISSET (int cpu, cpu_set_t * ensemble);); cf man CPU_ZERO on peut agir sur des process ou des threads int sched_setaffinity(pid_t pid, size_t taille_cpuset, cpu_set_t *ensemble); int pthread_setaffinity_np (pthread_t tid, size_t taille_cpuset, cpu_set_t *ensemble); ainsi que sched_getaffinity et pthread_getaffinity_np

33 Fonctions spécifiques de Xenomai
pthread_set_name_np donne un nom au thread utilisé pour l'affichage dans /proc/xenomai/sched int pthread_set_name_np(pthread_t tid, const char * name) pthread_set_mode_np établit les masques de mode du thread 2 masques : clrmask et setmask int pthread_set_mode_np(int clrmask, int setmas) les masques sont un OR des valeurs PTHREAD_LOCK_SCHED (valide quel que soit le mode) PTHREAD_SHIELD (valide uniquement en mode utilisateur) PTHREAD_RPIOFF idem PTHREAD_WARNSW idem PTHREAD_PRIMARY idem

34 Fonctions spécifiques de Xenomai
pthread_make_periodic_np rend un thread périodique int pthread_make_periodic_np(pthread_t tid, struct timespec *starttp, struct timespec *periodtp) starttp : date absolue de CLOCK_REALTIME jusqu'à laquelle le thread est bloqué periodtp : intervalle de temps correspondant à la période pthread_wait_np bloque le thread jusqu'à la fin de la période int pthread_wait_np(unsigned long *overruns) pour un thread périodique fait passer un thread utilisateur en thread primaire

35 signaux interruptions


Télécharger ppt "Gestion des tâches."

Présentations similaires


Annonces Google