Volatile Classe
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Contient des méthodes pour effectuer des opérations de mémoire volatile.
public ref class Volatile abstract sealed
public static class Volatile
type Volatile = class
Public Class Volatile
- Héritage
-
Volatile
Remarques
Sur un système multiprocesseur, en raison d’optimisations de performances dans le compilateur ou le processeur, les opérations de mémoire régulières peuvent sembler réorganisées lorsque plusieurs processeurs fonctionnent sur la même mémoire. Les opérations de mémoire volatile empêchent certains types de réorganisation par rapport à l’opération. Une opération d’écriture volatile empêche les opérations de mémoire antérieures sur le thread d’être réorganisées après l’écriture volatile. Une opération de lecture volatile empêche les opérations de mémoire ultérieures sur le thread d’être réorganisées avant la lecture volatile. Ces opérations peuvent impliquer des barrières de mémoire sur certains processeurs, ce qui peut affecter les performances.
Par exemple, considérez le scénario suivant avec deux threads et deux Int32 champs x et y qui sont initialement zéro :
| Thread 1 | Thread 2 |
|---|---|
x = 1; |
int y2 = Volatile.Read(ref y); |
Volatile.Write(ref y, 1); |
int x2 = x; |
La lecture et l’écriture volatiles empêchent la réorganisation des deux opérations au sein de chaque thread, par exemple par le compilateur ou par le processeur. Quel que soit l’ordre dans lequel ces opérations se produisent réellement sur un thread par rapport à l’autre thread, même sur un système multiprocesseur où les threads peuvent s’exécuter sur différents processeurs, les opérations volatiles garantissent que le thread 2 ne voit y2 == 1 pas et x2 == 0. Sur le thread 1, l’écriture doit x apparaître avant l’écriture volatile sur y, et sur le thread 2, la lecture x doit apparaître après la lecture volatile de y. Par conséquent, si le thread 2 voit y2 == 1, il doit également voir x2 == 1.
Toutefois, considérez le même scénario que ci-dessus avec une séquence spécifique dans laquelle les opérations se produisent :
| Série | Thread 1 | Thread 2 |
|---|---|---|
| 1 | x = 1; |
... |
| 2 | Volatile.Write(ref y, 1); |
... |
| 3 | ... |
int y2 = Volatile.Read(ref y); |
| 4 | ... |
int x2 = x; |
Même si l’écriture y volatile sur le thread 1 s’est produite avant la lecture volatile du y thread 2, le thread 2 peut toujours voir y2 == 0. L’écriture volatile à y ne garantit pas qu’une lecture y volatile suivante sur un autre processeur verra la valeur mise à jour.
Note
- Les lectures et écritures volatiles garantissent qu’une valeur est lue ou écrite en mémoire et non mise en cache (par exemple, dans un registre de processeur). Par conséquent, vous pouvez utiliser ces opérations pour synchroniser l’accès à un champ pouvant être mis à jour par un autre thread ou par matériel.
- La Volatile classe fournit également des opérations de lecture et d’écriture pour certains types 64 bits tels que Int64 et Double. Les lectures et écritures volatiles sur une telle mémoire 64 bits sont atomiques même sur des processeurs 32 bits, contrairement aux lectures et écritures régulières.
Les opérations de mémoire volatile sont destinées à des cas spéciaux de synchronisation, où le verrouillage normal n’est pas une alternative acceptable. Dans des circonstances normales, l’instruction C# lock, l’instruction Visual Basic SyncLock et la classe Monitor fournissent la méthode la plus simple et la moins sujette aux erreurs de synchronisation de l’accès aux données, et la classe Lazy<T> fournit un moyen simple d’écrire du code d’initialisation différée sans utiliser directement le verrouillage à double vérification.
Les Volatile.Read méthodes et Volatile.Write les méthodes activent les fonctionnalités qui ne sont pas prises en charge dans les langues. Par exemple:
Certains langages, tels que Visual Basic, ne reconnaissent pas le concept d’opérations de mémoire volatile. La Volatile classe fournit cette fonctionnalité dans de tels langages.
Note
L’appel d’une de ces méthodes n’affecte qu’un seul accès mémoire. Pour fournir une synchronisation efficace pour un champ, tous les accès au champ doivent utiliser Volatile.Read et Volatile.Write.
En C#, l’utilisation du
volatilemodificateur sur un champ garantit que chaque accès à ce champ est une opération de mémoire volatile, mais que levolatilemodificateur ne peut pas être appliqué aux éléments de tableau. Les méthodes et Volatile.Write les Volatile.Read méthodes peuvent être utilisées sur les éléments de tableau.
Méthodes
| Nom | Description |
|---|---|
| Read(Boolean) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(Byte) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(Double) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(Int16) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(Int32) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(Int64) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(IntPtr) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(SByte) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(Single) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(UInt16) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(UInt32) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(UInt64) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read(UIntPtr) |
Lit la valeur du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Read<T>(T) |
Lit la référence d’objet à partir du champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît après cette méthode dans le code, le processeur ne peut pas le déplacer avant cette méthode. |
| Write(Boolean, Boolean) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(Byte, Byte) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(Double, Double) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(Int16, Int16) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(Int32, Int32) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(Int64, Int64) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(IntPtr, IntPtr) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(SByte, SByte) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(Single, Single) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(UInt16, UInt16) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(UInt32, UInt32) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(UInt64, UInt64) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write(UIntPtr, UIntPtr) |
Écrit la valeur spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |
| Write<T>(T, T) |
Écrit la référence d’objet spécifiée dans le champ spécifié. Sur les systèmes qui en ont besoin, insère une barrière de mémoire qui empêche le processeur de réorganiser les opérations de mémoire comme suit : si une lecture ou une écriture apparaît avant cette méthode dans le code, le processeur ne peut pas le déplacer après cette méthode. |