Lorsque deux processeurs tentent d'accéder au même emplacement dans la mémoire globale au même instant, une condition de concurrence se produit. Le résultat dépend entièrement de l'architecture de la mémoire du système et de la manière dont il gère les accès simultanés. Il existe plusieurs possibilités :
* Comportement non défini : C’est le pire des cas. Le résultat de l'accès à la mémoire est imprévisible. L'écriture d'un processeur peut écraser celle de l'autre, ou des parties des deux peuvent être entrelacées, entraînant des données corrompues. Il n'y a aucune garantie quant au succès du fonctionnement du processeur ni à la manière dont les données seront affectées. Ceci est courant dans les systèmes sans aucun mécanisme de synchronisation d’accès à la mémoire.
* Corruption des données : L'écriture d'un processeur peut écraser les données écrites par l'autre processeur, entraînant une perte de données ou des valeurs incorrectes. C'est un résultat très courant s'il n'y a pas de synchronisation.
* Résultat arbitraire : Le matériel ou le système d'exploitation du système peut choisir l'accès d'un processeur pour réussir et l'autre pour échouer, ou il peut combiner les opérations de manière inattendue. Le résultat n’est pas déterministe.
* Arbitrage au niveau matériel : Certaines architectures peuvent disposer de mécanismes matériels (comme un arbitre de bus) qui donnent la priorité à un processeur par rapport à l'autre. Cela introduit un élément non déterministe, car la priorité peut varier en fonction de divers facteurs.
* Exception/Erreur : Le système peut détecter le conflit et générer une exception ou une erreur, interrompant potentiellement l'exécution ou provoquant le blocage du programme. Cependant, cela n'est pas garanti; de nombreux systèmes permettent simplement à la condition de concurrence critique de se poursuivre sans notification.
Pour éviter ces problèmes, les programmeurs doivent utiliser des mécanismes de synchronisation. Ces mécanismes appliquent l'ordre des accès à la mémoire, évitant ainsi les conditions de concurrence. Les exemples incluent :
* Mutex (exclusion mutuelle) : Un seul processeur peut détenir le mutex à un moment donné, empêchant ainsi l'accès simultané aux ressources partagées.
* Sémaphores : Plus général que les mutex, permettant un contrôle plus complexe de l'accès aux ressources partagées.
* Opérations atomiques : Opérations dont l'exécution est garantie de manière atomique (en tant qu'unité unique et indivisible), empêchant toute modification simultanée.
* Barrières/clôtures de mémoire : Ceux-ci imposent l'ordre des opérations de mémoire, garantissant que certaines opérations sont terminées avant que d'autres ne commencent.
En bref, un accès simultané au même emplacement mémoire sans synchronisation appropriée est une grave erreur de programmation pouvant conduire à un comportement imprévisible et peu fiable. Une programmation multiprocesseur robuste nécessite un examen attentif et la mise en œuvre de techniques de synchronisation.
|