2012-09-16 19 views
5

Wenn ein Thread A einen anderen Thread B mit dem einzigen Zweck erzeugt, in eine Variable V zu schreiben und dann darauf wartet, dass er beendet wird, sind Speicherbarrieren erforderlich, um sicherzustellen, dass nachfolgende Lesevorgänge von V auf Thread A frisch sind? Ich bin mir nicht sicher, ob es implizite Barrieren bei den Beendigungs-/Beitrittsvorgängen gibt, die sie überflüssig machen.Sind beim Verbinden eines Threads Speicherbarrieren erforderlich?

Hier ist ein Beispiel:

public static T ExecuteWithCustomStackSize<T> 
    (Func<T> func, int stackSize) 
{ 
    T result = default(T); 

    var thread = new Thread(
     () => 
       { 
        result = func(); 
        Thread.MemoryBarrier(); // Required? 
       } 
     , stackSize); 

    thread.Start(); 
    thread.Join(); 

    Thread.MemoryBarrier(); // Required? 
    return result; 
} 

entweder/beide (oder mehrere) der Barrieren in den obigen Schnipseln sind erforderlich?

+4

Ich bezweifle, dass beide Speicherbarriere erforderlich ist. Wenn sie dann wären, wäre Thread.Join ziemlich nutzlos und viele Leute wären in Schwierigkeiten. Join wartet, bis der Thread fertig ist, was die Zuweisung des Werts an die Variable beinhalten würde. – Despertar

+0

Siehe diesen Thread: http://stackoverflow.com/questions/6581848/memory-barrier-generators – Laurijssen

Antwort

0

Aus der Dokumentation sieht es aus wie sie nicht benötigt werden -

Memory auf Multiprozessorsystemen mit schwachen Speicherordnungs nur erforderlich ist (beispielsweise ein System mit mehreren Intel Itanium-Prozessoren verwendet wird).

Für die meisten Zwecke bieten die C# lock-Anweisung, die Visual Basic SyncLock-Anweisung oder die Monitor-Klasse einfachere Möglichkeiten zum Synchronisieren von Daten.

Da Sie blockieren mit Join ist es noch mehr nicht notwendig.

0

Sie benötigen die erste Speicherbarriere nicht. Sie müssen diese nur aufrufen, bevor Sie auf Daten zugreifen können, die in einem separaten Thread geändert wurden. Da Sie nicht innerhalb 'thread' tun, brauchen Sie den Anruf nicht.

Sie können die zweite loswerden, wenn Sie planen, den Anruf beizubehalten. Wenn Sie den zweiten Anruf behalten, können Sie Join loswerden.

3

Nein, Synchronisationsmechanismen generieren implizite Speicherzäune. Alle Daten, die von einem Thread geändert wurden, sind nach dem Verbinden des Threads sichtbar.

+1

Danke für Ihre Antwort. Irgendwelche Unterlagen, um dies zu untermauern? – Ani

+1

@Ani: In dieser Quelle: http://www.albahari.com/threading/part4.aspx (die jeder inzwischen kennt), erwähnen sie fast jeden Synchronisationsmechanismus als einen Zaun zu erzeugen. Sie erwähnen nicht explizit 'Join', aber da es den aufrufenden Thread zum Beispiel in den gleichen Zustand wie' Monitor.Wait' versetzt, ist das ein starker Hinweis, es sollte auch einen Zaun erzeugen. Darüber hinaus wird auch auf eine "Aufgabe" gewartet. Obwohl das Hinzufügen eines Threads etwas anders ist, erwarte ich, dass es die gleichen Speicherbestellgarantien bietet. – Tudor

+0

Ich habe das gelesen, war mir aber nicht sicher, ob das schlüssig war, da, wie Sie sagen, 'Join' nicht explizit erwähnt wurde. – Ani

Verwandte Themen