Frage Variablencaching


Warum in diesem Teil des Codes complete ist im Cache gespeichert?

static void Main()
{
  bool complete = false; 
  var t = new Thread (() =>
  {
    bool toggle = false;
    while (!complete) toggle = !toggle;
  });
  t.Start();
  Thread.Sleep (1000);
  complete = true;
  t.Join();        // Blocks indefinitely
}

aber in diesem Teil ist es nicht?

static void Main()
{
  bool complete = false;
  bool toggle = false; 
  var t = new Thread (() =>
  {
    while (!complete) toggle = !toggle;
  });
  t.Start();
  Thread.Sleep (1000);
  complete = true;
  t.Join();  
}

5
2018-02-28 22:43


Ursprung


Antworten:


Sie führen unsynchronisierte Datenfreigabe über Threads aus. Sirenen sollten jetzt gehen.

Wie ich das Speichermodell verstehe, darf das JIT lesen complete einmal und speichern Sie es in einem Register. Aus diesem Grund wird das Update von Main nie sichtbar.

Um dies zu beheben, ist es am einfachsten, eine Sperre um Zugriffe zu wickeln complete. Du könntest auch benutzen Thread.VolatileRead und Thread.VolatileWrite.


3
2018-02-28 23:45



Seien Sie nicht sicher, dass das Caching auf allen Architekturen wie oben geschehen wird oder dass es immer wie oben in mehreren Läufen des Programms passieren wird.

Es könnte sein weil im zweiten Fall das Lambda den Verschluss verändert, während es im ersten Fall nur auf den Verschluss zugreift. Natürlich ist das nur eine wilde Vermutung.

Wichtiger jedoch, Beim Caching gibt es keine Garantie werden getan werden, Speichergrenze nur angibt, wenn der Thread wird nicht Verwenden Sie den zwischengespeicherten Wert.

Unterm Strich können Sie sich nicht darauf verlassen, dass Caching stattfindet.


3
2018-02-28 23:50



Beide Beispiele sind in meinem Fall abgeschlossen, aber Sie können Lambda / Delegat in verschiedenen Compilern anders kompilieren, was das Problem sein könnte.

Sie delegieren auf eine geänderte Schließung, was zu einer Reihe von Problemen führen kann und Sie haben offenbar eine gefunden. Werfen Sie einen Blick auf die Antwort von Jon Skeet hier, Zugriff auf Modified ClosureEs ist nicht genau das gleiche Problem, aber der hier beschriebene Grund funktioniert auch bei Ihnen.


0
2018-02-28 22:59