Je voudrais coder un petit programme qui illustre visuellement le comportement du volatile
mot - clé. Idéalement, ce devrait être un programme qui effectue un accès simultané à un champ statique non volatil et qui obtient un comportement incorrect à cause de cela.
L'ajout du mot-clé volatile dans le même programme devrait résoudre le problème.
C'est quelque chose que je n'ai pas réussi à réaliser. Même en essayant plusieurs fois, en activant l'optimisation, etc., j'obtiens toujours un comportement correct sans le mot-clé «volatile».
Avez-vous une idée sur ce sujet? Savez-vous comment simuler un tel problème dans une simple application de démonstration? Cela dépend-il du matériel?
Oui, cela dépend du matériel (vous ne verrez probablement pas le problème sans plusieurs processeurs), mais cela dépend également de l'implémentation. Les spécifications du modèle de mémoire dans la spécification CLR permettent des choses que l'implémentation Microsoft du CLR ne fait pas nécessairement.
la source
Ce n'est pas vraiment une question de faute qui se produit lorsque le mot-clé 'volatile' n'est pas spécifié, plus qu'une erreur peut se produire lorsqu'elle n'a pas été spécifiée. En général, vous saurez quand c'est le cas mieux que le compilateur!
La façon la plus simple d'y penser serait que le compilateur puisse, s'il le voulait, incorporer certaines valeurs. En marquant la valeur comme volatile, vous vous dites, ainsi qu'au compilateur, que la valeur peut réellement changer (même si le compilateur ne le pense pas). Cela signifie que le compilateur ne doit pas aligner les valeurs, garder le cache ou lire la valeur tôt (dans une tentative d'optimisation).
Ce comportement n'est pas vraiment le même mot clé qu'en C ++.
MSDN a une brève description ici . Voici un article peut-être plus approfondi sur les sujets de la volatilité, de l'atomicité et de l'imbrication
la source
C'est difficile à démontrer en C #, car le code est abstrait par une machine virtuelle, donc sur une implémentation de cette machine, il fonctionne correctement sans volatil, alors qu'il peut échouer sur une autre.
Wikipédia a cependant un bon exemple pour le démontrer en C.
La même chose pourrait se produire en C # si le compilateur JIT décide que la valeur de la variable ne peut pas changer de toute façon et crée ainsi un code machine qui ne la vérifie même plus. Si maintenant un autre thread modifiait la valeur, votre premier thread pourrait encore être pris dans la boucle.
Un autre exemple est occupé en attente.
Encore une fois, cela pourrait également arriver avec C #, mais cela dépend fortement de la machine virtuelle et du compilateur JIT (ou de l'interpréteur, s'il n'a pas de JIT ... en théorie, je pense que MS utilise toujours un compilateur JIT et aussi Mono utilise one; mais vous pourrez peut-être le désactiver manuellement).
la source
Voici ma contribution à la compréhension collective de ce comportement ... Ce n'est pas grand chose, juste une démonstration (basée sur la démo de xkip) qui montre le comportement d'un volatile vers une valeur int non volatile (ie "normale"), côte à côte -côté, dans le même programme ... c'est ce que je cherchais quand j'ai trouvé ce fil.
Il y a quelques excellentes explications succinctes ci-dessus, ainsi que quelques bonnes références. Merci à tous de m'avoir aidé à comprendre
volatile
(au moins assez pour savoir ne pas se fier àvolatile
mon premier instinctlock
).Bravo et merci pour TOUS les poissons. Keith.
PS: Je serais très intéressé par une démo de la requête originale, qui était: "Je voudrais voir un int statique volatile se comporter correctement là où un int statique se comporte mal.
J'ai essayé et échoué ce défi. (En fait j'ai abandonné assez rapidement ;-). Dans tout ce que j'ai essayé avec des variables statiques, ils se comportent "correctement", qu'ils soient volatils ou non ... et j'aimerais une explication de POURQUOI c'est le cas, si c'est effectivement le cas ... le compilateur ne met pas en cache les valeurs des variables statiques dans les registres (c'est-à-dire qu'il met en cache une référence à cette adresse de tas à la place)?
Non , ce n'est pas une nouvelle question ... il est une tentative de la communauté TSAR revenir à la question initiale.
la source
Je suis tombé sur le texte suivant de Joe Albahari qui m'a beaucoup aidé.
J'ai pris un exemple du texte ci-dessus que j'ai un peu modifié, en créant un champ volatil statique. Lorsque vous supprimez le
volatile
mot - clé, le programme se bloque indéfiniment. Exécutez cet exemple en mode Release .la source