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

Threads Posix.1c/1003b IEEE IEEE Présentation Création.

Présentations similaires


Présentation au sujet: "Threads Posix.1c/1003b IEEE IEEE Présentation Création."— Transcription de la présentation:

1 Threads Posix.1c/1003b IEEE IEEE Présentation Création

2 Présentation Un thread est un déroulement d'un programme qui s'exécute parallèlement à d'autres unités en cours d'exécution. Les différents threads d'une application partagent un même espace d'adressage. L'accès concurrentiel aux mêmes données nécessite une synchronisation pour éviter les interférences. En outre chaque thread dispose d'une pile et d'un contexte d'exécution contenant les registres du processeur et un compteur d'instruction. L'idée générale est de détacher le flot d'exécution des ressources

3 Le contexte processus Contexte d'exécution Registres généraux Registres d'état SP PC Contexte du noyau Tables fichiers Structure MV Segment données Pile Tas Données code Code données et pile Contexte du processus

4 Le contexte processus : Détacher le flot des ressources Contexte du thread Registres généraux Registres d'état SP PC Contexte du noyau Tables fichiers Structure MV Segment données Pile Tas Données code Code et données Thread

5 Processus multi-thread Contexte du noyau Tables fichiers Structure MV Segment données Tas Données code Code et données Contexte du thread Registres généraux Registres d'état SP2 PC2 Pile2 Thread 2 Contexte du thread Registres généraux Registres d'état SP1 PC1 Pile1 Thread 1

6 La bibliothèque des threads 0.9/man3/pthread_create.3.htmlwww.linux-kheops.com/doc/man/manfr/man-html- 0.9/man3/pthread_create.3.html

7 Le man Nom pthread_create - créé un nouveau thread Synopsis #include int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg); Description pthread_create créé un nouveau thread s'éxécutant concurremment avec le thread appelant. Le nouveau thread exécute la fonction start_routine en lui passant arg comme premier argument. Le nouveau thread s'achève soit explicitement en appelant pthread_exit(3), ou implicitement lorsque la fonction start_routine s'achève. Ce dernier cas est équivalent à appelér pthread_exit(3) avec la valeur renvoyée par start_routine comme code de sortie. L'argument attr indique les attributs du nouveau thread. Voir pthread_attr_init(3) pour une liste complète des attributs. L'argument attr peut être NULL, auquel cas, les attributs par défaut sont utilisés: le thread créé est joignable (non détaché) et utilise la politique d'ordonnancement usuelle (pas temps-réél).pthread_exit(3) pthread_exit(3) pthread_attr_init(3) Valeur Renvoyée En cas de succès, l'identifiant du nouveau thread est stocké à l'emplacement mémoire pointé par l'argument thread, et 0 est renvoyé. En cas d'erreur, un code d'errur non nul est renvoyé. Erreurs EAGAIN pas assez de ressources système pour créer un processus pour le nouveau thread. EAGAIN il y a déjà plus de PTHREAD_THREADS_MAX threads actifs. Auteur Xavier Leroy Traduction Thierry Vignaud, 2000 Voir Aussi pthread_exit(3)pthread_exit(3), pthread_join(3), pthread_detach(3), pthread_attr_init(3).pthread_join(3)pthread_detach(3) pthread_attr_init(3)

8 pthread.h ftp://sources.redhat.com/pub/pthreads-win32/dll-latest/include/ lien

9 Création d'un thread Un type opaque est utilisé pour distinguer les threads d'une application unsigned long pthread_t (dans la bibliothèque LinuxThreads) Création d'un thread int pthread_create( 1.pthread_t * pThread, 2.const pthread_attr_t * attr, 3.void* (*pFunction) (void*), 4.void * pArg ); Cette routine renvoie 0 si elle a réussi, sinon elle renvoie un numéro de lerreur survenue. pthread_create ne remplit pas la var errno.

10 Le code C de thread_create /* Thread creation */ int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void * (*start_routine)(void *), void *arg) { pthread_descr self = thread_self(); struct pthread_request request; if (__pthread_manager_request < 0) { if (pthread_initialize_manager() < 0) return EAGAIN; } request.req_thread = self; request.req_kind = REQ_CREATE; request.req_args.create.attr = attr; request.req_args.create.fn = start_routine; request.req_args.create.arg = arg; sigprocmask(SIG_SETMASK, (const sigset_t *) NULL, &request.req_args.create.mask); __libc_write(__pthread_manager_request, (char *) &request, sizeof(request)); suspend(self); if (self->p_retcode == 0) *thread = (pthread_t) self->p_retval; return self->p_retcode; }

11 Arguments 1.Le premier argument pthread_t * pThread, est un pointeur qui sera réalisé par la routine avec l'identifiant du nouveau thread. 2.le second argument const pthread_attr_t * attr, correspond aux attributs dont on desire doter le nouveau thread. Par défaut, le thread reçoit des attributs standard. 3.Le troisième argument void* (*pFunction) (void*), est un pointeur représentant la fonction principale du nouveau thread (c'est ce qu'il doit faire). Dès la création du thread, la fonction est invoquée en recevant comme argument le pointeur passé en dernière position. Le prototype de cette fonction est imposé et ne peut donc pas être modifié. 4.Le quatrième argument void * pArg est de type void *, il sera ainsi transformé dans le type de l'argument que l'on veur passer au thread. Cet argument est généralement un numéro permettant d'indiquer le travail à réaliser.

12 Terminaison La terminaison a lieu lorsque 1.La fonction principale se termine. 2.Par l'appel de la fonction pthread_exit le thread est alors éliminé par l'appel de pthread_exit toutes les fonctions de nettoyage sont invoquées

13 Terminaison Prototype de la fonction void pthread_exit(void * pReturnValue);

14 Récupération d'une valeur de retour Pour avoir la valeur de retour d'un thread terminé on utilise int pthread_join( 1.pthread_t thread, 2.void ** pPtrReturnValue ); La fonction peut échouer si le thread attendu n'existe pas ; s'il est détaché ou si le thread demande sa propre fin

15 Les argument de pthread_join L'argument pthread_t thread, est le thread qui se termine Le deuxième argument void ** pPtrReturnValue est un pointeur sur un void * utilisé pour recevoir la valeur de retour du thread. Cette valeur de retour est spécifiée a la fin du thread grâce a la fonction pthread_exit. Ce dernier argument peut être NULL si nous ne sommes pas intéressé par la valeur de retour du thread.

16 Récupération d'un entier comme code de retour Pour conserver la portabilité d'un programme, la procédure a lieu en deux étapes 1.dans fonctionthread int i=valretour; pthread_exit((void*)i); 2.dans le main par exemple void * retour; pthread_join(threadid, & retour); Ainsi, il faut utiliser d'abord un pointeur void * temporaire, qu'on transforme ensuite en int.

17 Interaction avec le thread principal Thread Principal Fin pthread_create() pthread_join() fin pthread_join() exit() thread ptread_exit() pthread_create()

18 Synchronisation et communication de tâches Dans POSIX, les outils sont plus rapides et plus puissants que les IPC Sémaphore binaire Les mutex sont dédiés à l'exclusion mutuelle. Les attributs des mutex permettent de choisir le protocole de gestion de ressource associé Sémaphores en lecture/écriture POSIX.1c propose les sémaphore en lecture/écriture Aucun protocole de gestion de ressources Variable conditionnelle Utilisée avec un mutex pour créer des moniteurs On peut utiliser une attente bornée qui ne sera jamais signalée. RDV Après la création d'un RDV synchronisé des tâches peuvent s'attendre mutuellement

19 zones d'exclusions mutuelles La synchronisation est un des enjeux essentiels du développement d'application multithreads entre les différents fils d'exécution concurrents. Pour accéder à des données communes, il est indispensable de mettre en œuvre un mécanisme d'exclusion mutuelle des threads. Cas des mutex Pour créer un mutex, la librairie POSIX fournie la fonction suivante : int pthread_mutex_init( 1.pthread_mutex_t * pMutex, 2.pthread_mutexattr_t * pAttributs ); Pour détruire un mutex, nous utilisons la fonction suivante : int pthread_mutex_destroy(pthread_mutex_t * pMutex);

20 Paramètres Le premier paramètre est un pointeur sur un pthread_mutex_t destiné a recevoir le descripteur du mutex nouvellement créé. Le second paramètre pAttributs est utilisé pour paramétrer le mutex, cette variable regroupe tous les attributs du mutex, les paramètres par défaut sont obtenus avec un pointeur Null.

21 Emploi La fonction pthread_mutex_init est employée comme ceci pthread_mutex mutex pthread_mutexattr_t muxeattr /*initialisationdemutexattr*/ /*initialisationdumutex*/ if ((mutex=malloc (sizeof(pthread_mutex_t))==Null) return (-1); pthread_mutex_init(&mutex,&mutexattr);

22 Fonction de verrouillage et déverrouillage Si le mutex est libre, il peut être immédiatement verrouillé et attribué au thread appelant. Si le mutex est déjà maintenu par un autre thread, la fonction reste bloquée (indéfiniment). Ce n'est pas un point d'annulation. int pthread_mutex_lock(pthread_mutex_t * pMutex); Dès que le thread a fini de travailler avec les données protégées, le mutex doit être déverrouillé pour laisser la place a dautres thread. Ceci est simplement réalisé en appelant la fonction suivante : int pthread_mutex_unlock(pthread_mutex_t * pMutex);

23 Attente conditionelle Lorsqu'un processus attend qu'un événement survienne on emploie une technique de synchronisation a base de variable conditionnelle. Un thread attend une condition ; il est avertit par un autre thread lorsqu'elle est réalisée. Lorsquun variable de condition nest plus utilisée, il faut la libérée avec la fonction suivante : int pthread_cond_destroy(pthread_cond_t * pCond);

24 Attente conditionelle Le principe repose sur deux fonctions de manipulation des conditions int pthread_cond_wait( pthread_cond_t * pCond, pthread_mutex_t * pMutex ); int pthread_cond_signal(pthread_cond_t * pCond); Sans oublier int pthread_cond_init( pthread_cond_t * pCond, pthread_condattr_t * pCandAttr );

25 Scénario Toutes les variables de condition ont besoin dêtre associé à un mutex spécifique qui va bloquer le thread jusqu'à lémission de la notification. Thread attendant la conditionThread signalant la condition pthread_mutex_lock pthread_cond_wait déblocage du mutex wait pthread_mutex_lock pthread_cond_signal Réveil du thread pthread_cond_wait Tentative de récupérer le mutex pthread_mutex_unlock Fin de pthread_cond_wait pthread_mutex_unlock

26 Fonction d'attente temporisée Il faut préciser l'heure maximale et non la durée int pthread_cond_timewait( 1.pthread_cond_t * pCond, 2.pthread_mutex_t * pMutex, 3.struct timespec * expiration ); pthread_cond_wait a le comportement d'un point d'annulation. Lorsqu'un thread reçoit une demande d'annulation durant cette fonction d'attente, elle se termine mais doit récupérer avant le mutex associé à la condition. Cela signifie qu'elle peut bloquer indéfiniment avant de se terminer.

27 Annulation d'un thread L'annulation doit thread doit laisser les données dans un état prévisible, et le seul état prévisible du mutex associé à un appel pthread_cond_wait() est le verrouillage. Bien sur, le thread ne doit pas laisser le mutex bloqué. On utilise une fonction de nettoyage.

28 Fonction de nettoyage Lorsqu'un thread s'attribue une ressource qui nécessite une libération ultérieure, il enregistre le nom de la routine de libération dans une pile spéciale. Lorsque le thread se termine, les routines sont dépilées et exécutées void pthread_cleanup_push( 1.void(*fonction)(void * argument), 2.void * argument ); void pthread_cleanup_pop(int execution_routine);

29 Ordonnancement Deux niveaux de programmation concurrente sont offert dans Posix les processus et les threads L'ordonnancement peut se faire à deux niveaux local et global

30 Ordonnancement local 1 2 n P1P4P12 Pi TiTj Le modèle d'ordonnancement est hiérarchique Les processus sont en concurrence par priorité Le temps alloué à P4 est réparti aux taches

31 Ordonnancement global 1 2 n P1P4P12 Pi TiTj T1 T2 Les taches ou les processus sont ordonnancées au même niveau

32 Ordonnancement Mixte 1 2 n P1P4P12 Pi TiTj T1 T2

33 Avantages/inconvénients Dans un ordonnancement local si une tâche fait une action bloquante le processus est bloqué. Les tâches d'un même processus ne peuvent être ordonnancées sur un multiprocesseurs Pour modifier dans un ordonnancement global un paramètre influençant l'ordonnancement il faut faire un appel système plus lourd qu'un appel de fonction interne au processus. Les tâches d'un même processeurs peuvent être ordonnancées sur plusieurs processeurs

34 Politique d'ordonnancement SCHED_FIFO La tâche prête (processus) qui a la plus forte priorité au niveau global et qui est arrivée la première SCHED_RR fonctionne comme SCHED_FIFO avec un quantum de temps appliqué par tourniquet SCHED_OTHER défini par l'implémentation SCHED_SPORADIC La politique de base est la politique SCHED_FIFO, avec une quantité de temps alloué à un serveur dont la capacité est cette quantité

35 Les attributs d'une tâche Les attributs d'une tâches peuvent définir Le type d'ordonnancement à appliquer La taille de la pile Une priorité La définition d'un serveur sporadique associé à la tâche L'état attaché ou détaché de la tâche Après la création d'un tâche, il est possible de modifier les attributs d'une tâche.

36 Les attributs de thread Création et destruction : int pthread_attr_init ( pthread_attr_t * ) int pthread_attr_destroy (pthread_attr_t * ) Lecture : int pthread_attr_getXXX (const pthread_attr_t *, T*) Mise à jour : int pthread_attr_setXXX ( pthread_attr_t *, T ) XXX représente le nom de l'attribut.

37 Signification et valeur de XXX detachstate : spécifie sil sera possible de se synchroniser sur le fil dexécution une fois quil sera terminé. PTHREAD_CREATE_JOINABLE pour autoriser la synchronisation PTHREAD_CREATE_DETACHED pour la décliner. schedpolicy correspond à la politique dordonnancement employée par le thread. SCHED_OTHER pour lordonnancement classique SCHED_RR pour un séquencement temps-réel avec lalgorithme Round Robin SCHED_FIFO pour un ordonnancement temps-réel FIFO. Inheritsched signale si le thread a sa propre configuration d'ordonnancement PTHREAD_EXPLICIT_SCHED ordonnancement spécifique au thread PTHREAD_INHERIT_SCHED ordonnancement hérité

38 Liste complète int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy); int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param); int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param); int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit); int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit); int pthread_attr_setscope(pthread_attr_t *attr, int scope); int pthread_attr_getscope(const pthread_attr_t *attr, int *scope);

39 Norme POSIX.1003.b

40 liens


Télécharger ppt "Threads Posix.1c/1003b IEEE IEEE Présentation Création."

Présentations similaires


Annonces Google