Synchronisation (multitâches) - Définition

Source: Wikipédia sous licence CC-BY-SA 3.0.
La liste des auteurs de cet article est disponible ici.

Introduction

Dans le contexte de la programmation concurrente, le terme de synchronisation se réfère à deux concepts distincts mais liés : la synchronisation de processus et la synchronisation de données. Alors que la synchronisation de processus est un mécanisme qui vise à bloquer l'exécution des différents processus à des points précis de leur programme de manière à ce que tous les processus passent les étapes bloquantes au moment prévu par le programmeur, la synchronisation de donnée est un mécanisme qui vise à conserver la cohérence entre différentes données dans un environnement multitâche. Initialement cette notion de synchronisation est apparue pour la synchronisation de données.

Ces problèmes dit de « synchronisation » et même plus généralement ceux de communication inter-processus dont ces derniers dépendent, rendent pratiquement toujours la programmation plus difficile. Certaines méthodes de programmation cherchent à éviter d'utiliser ces verrous, appelées Non-blocking synchronization, elles sont encore plus difficiles à mettre en œuvre et nécessitent la mise en place de structure de données très particulières. La mémoire transactionnelle logicielle en est une.

Description de quelques problèmes

Dans l'illustration suivante, le résultat n'est pas prévisible, du fait que vous ne pouvez savoir quand les Thread A et B s'exécute. Dans l'hypothèse la plus simple ou les thread A et B s'exécutent une fois, l'ordre d'exécution des instructions peut être par exemple : Lire, Lire, Add, Add, Écrire, Écrire ou Lire, Add, Écrire, Lire, Add, Écrire. Le résultat dans ces deux hypothèses n'est pas le même puisque au final dans le second cas la variable est augmentée de 2 alors qu'elle n'est augmentée que de un dans le premier.

Exemple d'erreur d'accès sur une variable
Thread A Thread B
1A: Lire variable V 1B: Lire variable V
2A: Add 1 à la variable V 2B: Add 1 à la variable V
3A: Écrire la variable V 3B: Écrire la variable V

Si l'instruction 1B est exécutée entre 1A et 3A, ou si l'instruction 1A est exécutée entre 1B et 3B, le programme produira des données incorrectes. Ce phénomène est connu sous le nom de situation de compétition. Pour résoudre ce genre de problème, le système doit permettre au programmeur d'utiliser un verrou d'exclusion mutuelle, c'est-à-dire de pouvoir bloquer, en une seule instruction, tous les processus tentant d'accéder à cette donnée, puis, que ces processus puisse y accéder enfin lorsque la variable est libérée. La tâche attendant la levée du verrou est dite « mise en sommeil ». Ces opérations de verrouillage en une instruction sont dites « atomique », du grec ατομος [atomos], qui signifie que l'on ne peut diviser. Il existe concrètement plusieurs techniques pour obtenir des verrous et des sections critiques où l'accès au données est « sécurisé » comme ceci :

Exemple d'erreur d'accès sur plusieurs variables
Thread A Thread B
1A: Verrouiller la variable V 1B: Verrouiller la variable V
2A: Lire la variable V 2B: Lire la variable V
3A: Add 1 à la variable V 3B: Add 1 à la variable V
4A: Écrire la variable V 4B: Écrire la variable V
5A: déverrouiller la variable V 5B: déverrouiller la variable V

Ce genre de mécanismes est cependant source potentiel de bug informatique, en effet si deux tâches doivent chacune lire et écrire deux variables et qu'il y accèdent en même temps, cela doit être fait avec précaution. En effet, la première tâche verrouille la première variable pendant que la seconde tâche verrouille la seconde, les deux tâches seront mise en sommeil. Il s'agit la d'un cas d'interblocage, autrement appelé d'« étreinte mortel » ou « étreinte fatale ». Un fort couplage augmente le risque de bugs.

Page générée en 0.091 seconde(s) - site hébergé chez Contabo
Ce site fait l'objet d'une déclaration à la CNIL sous le numéro de dossier 1037632
A propos - Informations légales
Version anglaise | Version allemande | Version espagnole | Version portugaise