Atomarität des C # zusammenwachsenden Betreibers

7

Ich habe heute in unserer Codebasis einen Singleton-Code gefunden und war mir nicht sicher, ob das Folgende Thread-sicher war:

%Vor%

Diese Aussage entspricht:

%Vor%

Ich glaube das? ist nur ein Compiler-Trick und der resultierende Code ist immer noch NICHT atomar. Mit anderen Worten, zwei oder mehr Threads könnten _sentence als null finden, bevor _sentent auf einen neuen Satz gesetzt und zurückgegeben wird.

Um Atomizität zu garantieren, müssten wir diesen Code einsperren:

%Vor%

Stimmt das?

    
Adam 23.02.2012, 19:57
quelle

3 Antworten

11

Sie haben Recht; es ist überhaupt nicht Thread-sicher.

    
SLaks 23.02.2012, 19:58
quelle
15
  

Ich habe heute in unserer Codebase einen Singleton-Code gefunden

Haben Sie in Ihrer Codebase einen solchen verschleierten Code? Dieser Code macht das Gleiche:

%Vor%

und ist ungefähr tausendmal einfacher zu lesen.

  

Ich glaube das? ist nur ein Compiler-Trick und der resultierende Code ist immer noch NICHT atomar

Sie haben Recht. C # macht die folgenden Atomaritätsgarantien:

  

Lese- und Schreibvorgänge der folgenden Datentypen sind atomar: bool, char, byte, sbyte, kurz, ushort, uint, int, float und reference types. Darüber hinaus sind Lese- und Schreibvorgänge von Aufzählungstypen mit einem zugrunde liegenden Typ in der vorherigen Liste ebenfalls atomar. Das Lesen und Schreiben anderer Typen, einschließlich langer, ulong-, doppelter und dezimaler sowie benutzerdefinierter Typen, ist nicht garantiert atomar. Abgesehen von den Bibliotheksfunktionen, die für diesen Zweck entwickelt wurden, gibt es keine Garantie für das atomare Lesen-Modifizieren-Schreiben, wie im Fall von Inkrement oder Dekrement.

Der Null-Koaleszenzoperator ist nicht in dieser Liste der Garantien enthalten.

  

Um Atomizität zu garantieren, müssten wir diesen Code einsperren:

%Vor%

Gute Himmel nein. Das stürzt sofort ab!

Das Richtige ist:

  • Versuchen Sie nicht, Multithreading-Code zu schreiben.
  • Schreiben Sie ein Singleton mit einem der sicheren Singleton-Muster, die Jon Skeet auf seiner Seite über Singletons dokumentiert.
  • Verwenden Sie die Klasse Lazy<T> .
  • Sperren Sie ein Objekt, das zum Sperren dieser Variable bestimmt ist.
  • Verwenden Sie einen Interlocked Compare Exchange, um einen atomaren Test durchzuführen und festzulegen.
Eric Lippert 23.02.2012 22:12
quelle
1

Sie können Interlocked.CompareExchange mit null verwenden, um ?? zu erhalten. esque Operation, die atomar ist.

%Vor%     
Austin Salonen 23.02.2012 20:07
quelle