Cet article est un article miroir de traduction automatique, veuillez cliquer ici pour accéder à l’article original.

Vue: 46741|Répondre: 7

[Source] Volatile vs. Interlocked vs. lock

[Copié le lien]
Publié sur 27/08/2018 14:40:35 | | |
Supposons qu’il existe une classe contenant un champ public de compteur int accessible par plusieurs threads, et ce nombre ne fera qu’augmenter ou diminuer.

Lors de l’ajout de ce champ, lequel des schémas suivants doit être utilisé, et pourquoi ?

  • lock(this.locker) this.counter++ ;
  • Interlocked.Increment(cf this.counter) ;
  • Changez le modificateur d’accès de compteur en volatile public


Pire (aucun ne fonctionne réellement)

Changez le modificateur d’accès de compteur en volatile public

Cette approche n’est en réalité pas du tout sécurisée, et le point avec le volatile est que plusieurs threads fonctionnant sur plusieurs CPU mettent en mémoire tampon les données et réarrangent les instructions exécutées.

Si elle est non volatile, lorsque le CPU A augmente d’une valeur, le CPU B doit attendre un certain temps pour voir cette valeur augmentée, ce qui peut entraîner des problèmes.

Si c’est volatil, cela garantit que les deux CPU voient la même valeur en même temps. Mais cela n’empêche pas les opérations de lecture et d’écriture transversales.

Ajouter de la valeur à une variable prend en réalité trois étapes

1. Lecture, 2. Ajouter 3. Écrire

Supposons que le thread A lit la valeur du compteur comme 1 et ne soit pas prêt à augmenter, alors le thread B lit également la valeur du compteur comme 1, et les deux threads commencent alors à effectuer des opérations incrémentales et d’écriture. La valeur du compteur final est de 2. Ce n’est pas correct, les deux threads ont effectué une opération d’augmentation, et le résultat correct devrait être 3. Donc le qualifier de volatil est tout simplement dangereux.

C’est mieux

lock(this.locker) this.counter++ ;

De cette façon, c’est sûr (n’oubliez pas de verrouiller partout où vous voulez accéder à ce compteur, bien sûr). Cela empêche tout autre thread d’exécuter le code verrouillé. Et cela évite aussi le problème de séquençage d’instructions multi-CPU mentionné plus haut. Le problème, c’est que le verrou est lent en performance, et si vous utilisez le verrou à d’autres endroits sans rapport, il peut bloquer vos autres threads.

Meilleurs

Interlocked.Increment(cf this.counter) ;

C’est sûr et très efficace. Il effectue la lecture, l’augmentation, l’écriture de trois opérations dans un atome sans être interrompu au milieu. Comme cela n’affecte pas d’autres codes, vous n’avez pas besoin de vous souvenir des serrures ailleurs. Et c’est aussi très rapide (comme le dit MSDN, sur les processeurs actuels, ce n’est souvent qu’une instruction).

Mais je ne suis pas tout à fait sûr que cela puisse aussi résoudre le problème d’ordre des instructions du CPU, ou s’il doit être utilisé en combinaison avec volatile et cet incrément.

Supplément : Quels problèmes les volatils résout-ils bien ?

Puisque le volatile ne peut pas empêcher le multithreading, que peut-il faire ? Un bon exemple est que vous avez deux threads, l’un écrit toujours sur une variable, disons que cette variable est queneLength, et l’autre lit toujours les données de cette variable. Si la longueur de file d’attente n’est pas volatile, le thread A peut être lu 5 fois, mais le thread B peut voir des données retardées, voire dans le mauvais ordre. Une solution est d’utiliser la serrure, mais dans ce cas, vous pouvez aussi utiliser volatile. Cela garantit que le thread B voit toujours les dernières données écrites par le thread A, mais cette logique ne fonctionne que si vous ne les lisez pas lors de l’écriture, et si vous ne l’écrivez pas lors de la lecture. Une fois que plusieurs threads veulent effectuer des opérations de lecture-modification-écriture, il faut utiliser Interlock ou lock.





Précédent:Méthode de chiffrement Java MD5
Prochain:Linq implémente les requêtes conditionnelles non dans et dans SQL
Publié sur 29/08/2018 16:21:42 |
Bonjour, le code que vous avez fait plus tôt qui combine les highcharts, les histogrammes empilés et les histogrammes perforables ? J’aimerais demander si vous pouvez envoyer un code qui peut être modifié sur l’interface https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light ?
Publié sur 29/08/2018 16:22:13 |
Tout le réseau n’est que votre ressource.
Publié sur 29/08/2018 16:22:55 |
Parce que les 90 années précédentes ne pouvaient pas laisser de message. ainsi
Publié sur 29/08/2018 16:40:40 |
Est-il pratique d’ajouter une information de contact ? Consulter avec vous
 Propriétaire| Publié sur 15/09/2018 13:10:16 |
private static int safeInstanceCount = 0 ; Opérer avec des atomes
System.Threading.Interlocked.Increment(réf. safeInstanceCount) ; Auto-augmentation 1
System.Threading.Interlocked.Decrement (réf. safeInstanceCount) ; Auto-moins 1
Publié sur 21/05/2020 16:43:54 |
Soutenez le propriétaire pour qu’il partage
 Propriétaire| Publié sur 11/06/2020 15:00:16 |
1. Concept

Dans un environnement multithread, les opérations qui ne sont pas interrompues par des mécanismes d’ordonnancement de threads ; Une fois cette opération lancée, elle s’exécute jusqu’à la fin, sans aucun changement de contexte (passage à un autre thread) entre les deux.

2. Classe

Classe statique System.Threading.Interlocked

3. Fonctions couramment utilisées (voir le reste)

1. statique publique int Décrement (réf. int localisation) ; Réduisez la valeur de la variable spécifiée sous forme d’opération atomique et stockez le résultat

Équivalent à un verrou(obj){i-- ; }

2. statique publique int Incrément(réf, localisation int) ; Incrémentez la valeur de la variable spécifiée sous forme d’opération atomique et stockez le résultat

Équivalent à lock(obj){i++ ; }
Démenti:
Tous les logiciels, supports de programmation ou articles publiés par Code Farmer Network sont uniquement destinés à l’apprentissage et à la recherche ; Le contenu ci-dessus ne doit pas être utilisé à des fins commerciales ou illégales, sinon les utilisateurs assumeront toutes les conséquences. Les informations sur ce site proviennent d’Internet, et les litiges de droits d’auteur n’ont rien à voir avec ce site. Vous devez supprimer complètement le contenu ci-dessus de votre ordinateur dans les 24 heures suivant le téléchargement. Si vous aimez le programme, merci de soutenir un logiciel authentique, d’acheter l’immatriculation et d’obtenir de meilleurs services authentiques. En cas d’infraction, veuillez nous contacter par e-mail.

Mail To:help@itsvse.com