Dieser Artikel ist ein Spiegelartikel der maschinellen Übersetzung, bitte klicken Sie hier, um zum Originalartikel zu springen.

Ansehen: 46741|Antwort: 7

[Quelle] Volatile vs. Interlocked vs. Lock

[Link kopieren]
Veröffentlicht am 27.08.2018 14:40:35 | | |
Angenommen, es gibt eine Klasse, die ein öffentliches Int-Zählerfeld enthält, auf das mehrere Threads zugreifen können, und diese Zahl steigt oder verringert sich nur.

Beim Hinzufügen dieses Feldes, welche der folgenden Schemata sollten verwendet werden und warum?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment (ref this.counter);
  • Ändere den Zugriffsmodifikator von Counter auf öffentlich volatil


Am schlimmsten (keine davon funktioniert wirklich)

Ändere den Zugriffsmodifikator von Counter auf öffentlich volatil

Dieser Ansatz ist tatsächlich überhaupt nicht sicher, und der Punkt bei volatile ist, dass mehrere Threads, die auf mehreren CPUs laufen, Daten puffern und ausgeführte Anweisungen neu anordnen.

Wenn es nicht flüchtig ist, muss CPU B nach einer Erhöhung von CPU A um einen Wert eine Weile warten, um den erhöhten Wert zu sehen, was zu Problemen führen kann.

Wenn es flüchtig ist, sorgt das dafür, dass beide CPUs gleichzeitig denselben Wert sehen. Aber es verhindert nicht, dass Lese- und Schreiboperationen querschneiden.

Um einer Variablen Mehrwert hinzuzufügen, braucht man tatsächlich drei Schritte

1. Lesen, 2. Fügen Sie hinzu 3. Schreiben Sie

Angenommen, Thread A liest den Wert von Zähler als 1 und ist nicht bereit zu steigen, dann liest Thread B auch den Wert von Zähler als 1, und dann beginnen beide Threads, inkrementelle und Schreiboperationen durchzuführen. Der Wert des finalen Zählers beträgt 2. Das ist nicht richtig, beide Threads haben eine Erhöhungsoperation durchgeführt, und das korrekte Ergebnis sollte 3 sein. Es ist also einfach unsicher, es als flüchtig zu bezeichnen.

Es ist besser

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

So ist es sicher (denk natürlich daran, überall zu verriegeln, wo du auf diesen Theke zugreifen möchtest). Es verhindert, dass andere Threads den gesperrten Code ausführen. Und es verhindert auch das oben erwähnte Problem der Multi-CPU-Befehlssequenzierung. Das Problem ist, dass Lock in der Performance langsam ist, und wenn du Lock an anderen, nicht verwandten Stellen verwendest, kann es deine anderen Threads blockieren.

Bestes

Interlocked.Increment (ref this.counter);

Das ist sicher und sehr effizient. Es führt Lesen, Erhöhen und Schreiben drei Operationen in einem Atom aus, ohne in der Mitte unterbrochen zu werden. Da es andere Vorschriften nicht beeinflusst, musst du dir keine Schlösser anderswo merken. Und es ist auch sehr schnell (wie MSDN sagt, ist es auf heutigen CPUs oft nur eine Anweisung).

Aber ich bin mir nicht ganz sicher, ob es auch das Problem der CPU-Befehlsreihenfolge lösen kann oder ob es in Kombination mit flüchtigem Zustand und diesem Inkrementement verwendet werden muss.

Supplement: Welche Probleme löst flüchtiger Stoff gut?

Da volatile Multithreading nicht verhindern kann, was kann es tun? Ein gutes Beispiel ist, dass du zwei Threads hast: Einer schreibt immer zu einer Variable, nehmen wir an, diese Variable ist queneLength, und der andere liest immer Daten aus dieser Variable. Wenn queueLenght nicht flüchtig ist, kann Thread A 5 Mal lesen, aber Thread B kann verzögerte Daten oder sogar Daten in der falschen Reihenfolge sehen. Eine Lösung ist Lock, aber in diesem Fall kannst du auch volatile verwenden. Das stellt sicher, dass Thread B immer die neuesten Daten sieht, die von Thread A geschrieben wurden, aber diese Logik funktioniert nur, wenn man sie beim Schreiben nicht liest, und wenn man sie nicht beim Lesen schreibt. Wenn mehrere Threads Lesen-Modifizieren-Schreib-Operationen durchführen wollen, musst du Interlocked oder Lock verwenden.





Vorhergehend:Java MD5-Verschlüsselungsmethode
Nächster:Linq implementiert nicht in und in konditionalen Abfragen in SQL
Veröffentlicht am 29.08.2018 16:21:42 |
Hallo, der Code, den du vorhin gemacht hast, der Highcharts, gestapelte Histogramme und drillbare Histogramme kombiniert? Ich möchte fragen, ob du einen Code senden kannst, der auf der https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light-Oberfläche bearbeitet werden kann?
Veröffentlicht am 29.08.2018 16:22:13 |
Das gesamte Netzwerk ist nur deine Ressource.
Veröffentlicht am 29.08.2018 16:22:55 |
Weil die vorherigen 90 Jahre keine Nachricht hinterlassen konnten. Also
Veröffentlicht am 29.08.2018 16:40:40 |
Ist es bequem, eine Kontaktinformation hinzuzufügen? Ich konsultiere dich
 Vermieter| Veröffentlicht am 15.09.2018 13:10:16 |
private statische int safeInstanceCount = 0; Mit Atomen arbeiten
System.Threading.Interlocked.Increment(ref safeInstanceCount); Selbsterhöhung 1
System.Threading.Interlocked.Decrement (siehe safeInstanceCount); Selbst-minus 1
Veröffentlicht am 21.05.2020 16:43:54 |
Unterstütze den Eigentümer beim Teilen
 Vermieter| Veröffentlicht am 11.06.2020 15:00:16 |
1. Konzept

In einer Multithread-Umgebung werden Operationen nicht durch Thread-Planungsmechanismen unterbrochen; Sobald diese Operation beginnt, läuft sie bis zum Ende, ohne dass ein Kontextwechsel (Wechsel zu einem anderen Thread) dazwischen.

2. Klasse

System.Threading.Interlocked statische Klasse

3. Gebräuchlich verwendete Funktionen (siehe die übrigen)

1. öffentliche statische Int Decrement (Referenz Int Location); Reduzieren Sie den Wert der angegebenen Variablen in Form einer atomaren Operation und speichern Sie das Ergebnis

Äquivalent zu lock(obj){i--; }

2. öffentliche statische int Increment (ref int Location); Erhöhen Sie den Wert der angegebenen Variablen in Form einer atomaren Operation und speichern Sie das Ergebnis

Äquivalent zu lock(obj){i++; }
Verzichtserklärung:
Alle von Code Farmer Network veröffentlichten Software, Programmiermaterialien oder Artikel dienen ausschließlich Lern- und Forschungszwecken; Die oben genannten Inhalte dürfen nicht für kommerzielle oder illegale Zwecke verwendet werden, andernfalls tragen die Nutzer alle Konsequenzen. Die Informationen auf dieser Seite stammen aus dem Internet, und Urheberrechtsstreitigkeiten haben nichts mit dieser Seite zu tun. Sie müssen die oben genannten Inhalte innerhalb von 24 Stunden nach dem Download vollständig von Ihrem Computer löschen. Wenn Ihnen das Programm gefällt, unterstützen Sie bitte echte Software, kaufen Sie die Registrierung und erhalten Sie bessere echte Dienstleistungen. Falls es eine Verletzung gibt, kontaktieren Sie uns bitte per E-Mail.

Mail To:help@itsvse.com