LPS : Linux : principes et programmation Système
Autres références Cnam Liban et cofares.netThis project is maintained by ISSAE
Soit les 2 processus suivant
P1 | P2 |
---|---|
|
|
Les exécutions possible sont:
Pour que cette application soit valide, il faut que toutes les séquences possibles donnent le même résultat pour les même conditions préalable. La validité du résultat ne peut pas être garantie si ces instructions manipulaient des données communes aux deux processus.
Prenons le cas x=x+1;
cette instruction se décompose en trois instructions élémentaires (au niveaux du langage machine)
Nous aurons donc un entrelacement entres ces 3 instructions en cas de parallélisme
ainsi si x == 0
après l’exécution concurrente de x=x+1 dans 2 processus.
x=x+1 | x=x+1
—|—
Le résultat est 1 ou 2. Ceci n’arriverait pas si l’instruction x=x+1 était atomique
Voir cet exemple Concurence
L’exclusion mutuelle est le mécanisme qui permet qu’une et une seule tâche accède à une ressource partagée à la fois à un instant donné. Pour cela, on utilise une variable spéciale appelée sémaphore d’exclusion mutuelle qui joue le rôle de verrou pour accéder à la ressource. Sous Posix, elle est mise en place via les 3 primitives suivants :
pthread_mutex_t verrou
pthread_mutex_init(pthread_mutex_t *verrou, const pthread_mutextattr_t *m_attr)
pthread_mutex_lock(pthread_mutex_t *verrou)
pthread_mutex_unlock(pthread_mutex_t *verrou)
Voir Les sémaphores, concept et implémentation
voir Solutions problèmes classiques avec Sémaphores
Une condition (abréviation pour “variable condition”) est un mécanisme de synchronisation permettant à un thread de suspendre son exécution jusqu’à ce qu’une certaine condition (un prédicat) sur des données partagées soit vérifiée. Les opérations fondamentales sur les conditions sont : signaler la condition (quand le prédicat devient vrai) et attendre la condition en suspendant l’exécution du thread jusqu’à ce qu’un autre thread signale la condition.
Une variable condition doit toujours être associée à un mutex (sémaphore d’exclusion mutuelle), pour éviter une condition concurrente où un thread se prépare à attendre une condition et un autre thread signale la condition juste avant que le premier n’attende réellement.
Il peut arriver qu’une condition soit placée sur une donnée partagée par plusieurs tâches. Ainsi, suivant les besoins, une tâche accédant à la donnée peut être endormie si la condition n’est pas vérifiée. Elle ne sera réveillée que lorsqu’une autre tâche accédera à cette donnée et rendra la condition vraie.
Les principaux éléments à connaître sur les variables conditions sont les suivants :
int pthread_cond_signal(pthread_cond_t *cond)
Si plusieurs tâches attendent sur une condition, l’utilisation de pthread_cond_signal(pthread_cond_t *cond) ne réveille que l’une d’entre elles. Les autres restent malheureusement endormies. Pour réveiller toutes les tâches, on utilise la fonction suivante : int pthread_cond_broadcast(pthread_cond_t *cond)