5 votes

Dois-je verrouiller une variable dans un thread si je n'ai besoin de sa valeur que dans d'autres threads, et pourquoi cela fonctionne-t-il si je ne le fais pas ?

Je suis conscient de <a href="https://stackoverflow.com/questions/859690/do-i-need-a-lock-when-only-a-single-thread-writes-to-a-shared-variable">cette question </a>mais je crois que mes préoccupations sont très différentes.

J'ai récemment créé une application SDL, en utilisant le threading et OpenGL. J'ai un thread qui tourne en boucle et qui met continuellement à jour l'état des objets que je dessine à l'écran. Les états sont très simples, il s'agit juste d'un tableau booléen (quand la valeur du tableau est vraie, je le dessine, quand elle est fausse, je ne le fais pas).

Actuellement, je n'ai pas de verrou mutex sur aucune de mes variables et tout fonctionne très bien. Même si seule la moitié du tableau d'état est mise à jour entre deux dessins, le taux de rafraîchissement est bien supérieur (ou au moins égal) au taux de mise à jour, il serait donc acceptable d'avoir un état à moitié mis à jour.

Au départ, j'ai commencé à travailler sur une idée similaire à celle-ci sur un système embarqué utilisant des interruptions. De temps en temps, une interruption se déclenche, met à jour le tableau d'état et l'exécution continue. Maintenant que je suis sur un ordinateur de bureau multi-core, et que je mets à jour le tableau d'état simultanément, je me demande pourquoi rien de mal ne se passe, puisque techniquement je lis et j'écris au même endroit de la mémoire. en même temps .

  • Est-ce un hasard, ou y a-t-il une raison pour laquelle il n'y a pas de violation d'accès à la mémoire ?
  • S'il est acceptable que l'état de la variable change juste avant, pendant ou juste après l'utilisation de la valeur, dois-je prendre la peine d'utiliser un verrou mutex ?

Merci pour votre aide.


Edit : Information supplémentaire - le tableau est créé dynamiquement, mais quand il est créé/supprimé, j'utilise un mutex (je me suis dit que l'accès à la mémoire supprimée ne serait pas bien vu :P).

8voto

R.. Points 93718

En théorie, il est complètement invalide (comportement non défini) d'accéder à la mémoire de cette manière sans synchronisation.

En pratique, c'est modérément sûr tant que :

  1. Un seul fil est en train d'écrire et les autres sont tous en train de lire.
  2. Vous ne vous préoccupez pas du fait que les lecteurs ne voient pas certains des changements apportés jusqu'à un certain moment plus tard (éventuellement bien plus tard que le moment où ils sont écrits.
  3. Vous vous fichez que les lecteurs voient hors service les changements, c'est-à-dire qu'ils voient certains changements qui ont été faits plus tard sans voir d'autres changements qui ont été faits plus tôt.

Les problèmes 2 et 3 ne se posent pas sur x86, mais peuvent se produire sur presque toutes les autres machines multi-coeurs/SMP du monde réel. Vous pourriez les atténuer avec un asm spécifique à la machine (ou des intrinsèques du compilateur) pour insérer barrières de mémoire aux points appropriés.

1voto

progrmr Points 32412

Les éléments du tableau de booléens peuvent être mis en place/lus avec une opération atomique, il n'y a pas besoin d'un mutex. Vous avez besoin d'un mutex pour protéger une structure et vous assurer qu'elle reste cohérente. Puisque vos booléens sont indépendants, il n'y a pas de problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X