En d'autres termes, puis-je faire quelque chose avec une variable volatile qui ne pouvait pas également être résolue avec une variable normale et la classe verrouillée? P>
5 Réponses :
Oui, vous pouvez regarder la valeur directement.
Tant que vous n'utilisez la classe verrouillée que pour accéder à la variable, alors il n'y a pas de différence. Ce que volatiles em> est-il indique au compilateur que la variable est spéciale et si elle optimise ne devrait pas supposer que la valeur n'a pas changé. P> prend cette boucle: p > bool done = false;
...
while(!done)
{
... do stuff which the compiler can prove doesn't touch done...
}
Vous pouvez faire la même chose avec verrouillé.Lead ().
Votre description de volatile est légèrement fausse. Vous décrivez C ++ volatile (pas de bien pour la multithreading). C # (et Java) Volatile Créez le compilateur Insérer des opérations de synchronisation lors de l'accès à la variable. En raison de la synchronisation, il est forcé de relire la variable à chaque fois, ce qui a un effet similaire à la volatilité C ++.
éditer: Question largement réécrit em> Pour répondre à cette question, j'ai divisé un peu plus loin dans la matière et j'ai découvert quelques choses sur Maintenant que nous avons les règles, nous pouvons définir une réponse à votre question: p> sémantiquement: non, car Scope: Oui, déclarant une variable Si vous me demandiez, ce dernier bit est le besoin réel réel de une citation du langage de programmation C # em> standard: p> pour les champs non volatils, optimisation
techniques qui considèrent que la réorganisation
Les instructions peuvent conduire à inattendus
et des résultats imprévisibles dans
programmes multithreads qui accèdent
champs sans synchronisation tels que
qui fournit par la Lock-énoncé em>.
Ces optimisations risquent d'être effectuées par
le compilateur, par le système d'exécution,
ou par matériel. Pour les champs volatils,
Ces optimisations de réorganisation sont
restreint: p>
une lecture d'un champ volatil est appelé un lecture volatile em> strong>. Une lecture volatile
a: acquérir une sémantique »; c'est-à-dire qu'il
est garanti de se produire avant tout
Références à la mémoire qui se produisent après
dans la séquence d'instructions. P> li>
Une écriture d'un champ volatil est appelé un écrit volatile em> fort>. UNE
L'écriture volatile a "libération
sémantique "; c'est-à-dire qu'il est garanti
arriver après toutes les références de mémoire
avant l'instruction d'écriture dans le
Séquence d'instruction. P> LI>
ul>
blockQuote> mise à jour: em> strong> question est en grande partie réécrit, corrigé ma réponse originale et ajouté une "vraie" réponse p> p> p> P> volatile code> et
Imbriqué code> que je n'étais pas au courant. Clarifions cela, non seulement pour moi, mais pour cette discussion et d'autres personnes qui lisent sur ceci: p>
volatile code> lecture / écriture est censé être à l'abri de la réorganisation. Ceci seulement em> signifie la lecture et l'écriture, il est pas em> nuire à toute autre action; li>
interclocké code> utilise des instructions d'assemblage atomique pour comparaisonxchange (
cmPxchg code>), incrément (
inc code>) etc; li>
interclocké code> utilise-t-il parfois un verrou ": a verrouillage du matériel sur les systèmes multi-processeurs ; Dans les systèmes UNI-processeur, il n'y a pas de verrouillage matériel; li>
interclocké code> est différent de
volatile code> en ce qu'elle utilise une clôture totale em>, où volatile utilise une demi-clôture. LI>
volatile code>. Cela ne peut pas arriver avec
interclocké code>.
volatileread code> et
volatilwrite code> avoir le même problème de réorganisation comme `volatile (lien grâce à Brian Gideon). Li>
ul>
volatile code> que vous ne pouvez pas faire avec
interclocké code>:
a = b code> où
a code> ou
b code> est volatile, mais c'est évident; li>
interclocké code>. En d'autres termes: vous pouvez être moins em> sûr avec
volatile code>, alors vous pouvez être avec
interclocké code>. Li>
volatile code> est plus rapide que
interclocké code>. li>
ol> li>
interclocké code> fournit simplement une superset d'opérations et est plus sûr d'utiliser car elle applique une clôture complète. Vous ne pouvez rien faire avec
volatile code> que vous ne pouvez pas faire avec
interclocké code> et que vous pouvez faire beaucoup em> avec
interclocké code> que vous ne pouvez pas faire avec volatile: p>
static volatile int x = 0;
x++; // non-atomic
static int y = 0;
Interlocked.Increment(y); // atomic
volatile code> le rend volatil pour chaque accès. Il est impossible de forcer ce comportement n'importe quel autre moyen, donc
volatile code> ne peut pas être remplacé par
en verrouillé code>. Ceci est nécessaire dans des scénarios où d'autres bibliothèques, interfaces ou matériels peuvent accéder à votre variable et la mettre à jour à tout moment ou besoin de la version la plus récente. P> Li>
ul>
volatile code> et peut le rendre idéal où deux processus partagent la mémoire et doivent lire ou écrire sans verrouillage. Déclarant une variable comme
volatile code> est beaucoup plus sûre dans ce contexte, puis forçant tous les programmeurs à utiliser
interclocké code> (que vous ne pouvez pas forcer par le compilateur). P>
Edit: La citation suivante faisait partie de ma réponse originale, je le laisserai dans; -) em> p>
La classe verrouillée ne doit pas nécessairement faire beaucoup avec une serrure et elle a (contrairement à la serrure), pas beaucoup de frais généraux attribués à celui-ci - sur la plupart des processeurs, les méthodes verrouillées sont implémentées comme une instruction unique.
Vous êtes correct, merci de pointer dessus. Regardant dans comparaisexchange code> (pensant qu'il ne serait pas atomique) SSCLI (Source CLI) SSCLI montre qu'il se traduit par une instruction de montage
CMPXCHG CODE> sur X86 processeurs et cette instruction est - Comme autre chose dans
Interlocké Code> - En effet atomique.
Que et d'autres corrections, plus la réécriture sont maintenant dans la réponse :)
Vous avez dit, vous ne pouvez pas appliquer l'accès Threadsafe à une variable sans mot de clé volatile. Mais vous pouvez définir une propriété qui utilise verrouillé.Read () et interclocked.exchange () dans son getter / Setter.
Cela déguisait une variable. Bien sûr, vous pouvez le faire. Mais cela ne change pas le fait que vous ne pouvez pas avoir une variable variable i> ou un champ i> de cette façon. Caché derrière une propriété rend le champ moins sujet à une erreur, mais à l'intérieur de la classe et de l'extérieur (briser OO par la réflexion), il est juste accessible, avec une insuffisance de fil et tout. OTOH, il n'est pas possible de donner l'adresse d'une propriété "volatilisée" à une fonction externe (API, matériels, sinon), vous devez remettre l'adresse du champ et aucune manière verrouillée peut aider alors.
Le passage d'une référence d'une variables volatiles perd sa volatilité, le compilateur vous avertira si vous l'essayez. Cependant, votre réponse est très bonne et épuisante :)
D'accord, mais n'est-ce pas un avertissement sur la référence i>, ce qui signifie que la lecture / écriture de la variable a toujours la même sémantique? Sinon, comment le CLR permettrait-il d'utiliser volatile code> pour les variables pouvant être écrites par d'autres libs ou même du matériel?
C'est un sujet assez complexe. Je trouve ERISEUP pour être l'une des sources les plus définitives et précises pour concepts multithreading dans le cadre .NET qui pourrait aider à répondre à votre question. P>
Mais, pour résumer rapidement, il y a beaucoup de chevauchement entre le mot-clé code> volatile code> et la classe en verrouillée code> jusqu'à la manière dont ils peuvent être utilisés. Et bien sûr, les deux vont au-delà de ce que vous pouvez faire avec une variable normale. P>
Très bon article! Il faudra un certain temps pour le lire et beaucoup plus longtemps pour le comprendre parfaitement
Je ne tenterai pas d'être une autorité sur ce sujet, mais je vous recommande vivement de jeter un coup d'œil à Regardez également la dernière partie de Cette réponse Quels détails Que volatile code> doit être utilisé pour. p>
L'article de Skeet est bon mais couvre simplement les bases. Je sais quel volatile est bon pour, mais la question était de savoir s'il y a une situation où vous ne pouvez pas remplacer volatile avec une méthode verrouillée?
Oui, vous pouvez obtenir des performances en utilisant une variable volatil au lieu d'une serrure. P>
Serrure est une barrière de mémoire complète qui peut vous donner les mêmes caractéristiques d'une variable volatil ainsi que d'autres. Comme cela a déjà été dit volatiles, il suffit de s'assurer que dans des scénarios multi-threads si une CPU modifie une valeur dans sa ligne de cache, l'autre processeur voit la valeur immédiatement mais ne garantit pas de verrouillage sémantique. P>
La chose est une serrure est beaucoup plus puissante que volatile et vous devez utiliser volatil lorsque vous pouvez éviter les serrures inutiles. p>
Je ne parlais pas de la déclaration de verrouillage, mais de la classe imbriquée, mais oui ce que vous avez dit est vrai
Je sais quel volatile est bon pour. La question est de savoir s'il y a une situation où vous ne pouvez pas remplacer volatile avec une méthode verrouillée?