Bonjour,
j'aimerai bien comprendre comment se fait l'accès par défaut à un membre static. autrement dit est il nécessaire de déclarer le membre volatile pour permettre l'accès à plusieurs threads en même temps ?
Bonjour,
j'aimerai bien comprendre comment se fait l'accès par défaut à un membre static. autrement dit est il nécessaire de déclarer le membre volatile pour permettre l'accès à plusieurs threads en même temps ?
Bon je l'ai déduit en actant des cas exemples.
Merci bien
Bonjour,
Non, le mot clé volatile n'est pas requis pour l'utilisation d'une variable statique par plusieurs thread.
C'est un mot clé rarement utilisé, car rarement nécessaire. En effet, généralement, lorsqu'une variable peut être accédée par plusieurs threads, ses accès son protégé par un mécanisme comme un mutex, qui garantie qu'un thread manipulant une variable a un instant donné est le seul à cet instant précis.
Le mot clé volatile n'est utile que si un tel mécanisme de protection n'est pas mis en place, et pour s'assurer que toutes modifications de la variable par un thread soit immédiatement prise en compte par le second thread. Un exemple classique est l'attente active
Ici, sans le mot clé, la boucle du thread 1 a de très grande chance de ne jamais s'arrêtée en cas d'optimisation du code, même une fois que le thread 2 aura changé la valeur de la variable stop à true, car la valeur de la variable peut avoir été mise en cache. Avec le mot clé volatile, on s'assure que chaque accès à la variable est faite depuis la mémoire, assurant ainsi qu'il s'agit bien de la valeur courante.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 // sto pest une variable globale //bool stop; // thread 1 stop = false; while (!stop) { } // thread 2 ... stop = true ...
Non non, j'ai bien dis "jamais". Les optimisations peuvent parfois générer des comportements inattendu ! Et c'est le genre de problème très difficile à découvrir lorsqu'il se produit.
[EDIT]
Pour parfaire mes propos, voici un code d'exemple en C#
Exécuter ce code sans optimisation ne génère pas de problème chez moi. Exécuter ce code avec les optimisations activées génère une boucle infinie. Donc... jamais est tout à fait d'actualité.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MotCleVolatile { class Program { private bool stop; static void Main(string[] args) { var test = new Program(); new Thread(delegate () { Thread.Sleep(1000); test.stop = true; }).Start(); while (!test.stop) ; Console.WriteLine("OK"); } } }
[/EDIT]
Partager