2012-09-16 10 views
5

Se un thread A genera un altro thread B con il solo scopo di scrivere su una variabile V e quindi attende che termini, sono necessarie barriere di memoria per garantire che le letture successive di V sul thread A siano fresche? Non sono sicuro che ci siano barriere implicite nelle operazioni di terminazione/unione che le rendono ridondanti.Sono necessarie barriere di memoria quando si unisce a un thread?

Ecco un esempio:

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; 
} 

Sono sono o/sia (o più) delle barriere del frammento precedente richiesta?

+4

Dubito che sia necessaria una barriera di memoria. Se fossero allora Thread.Join sarebbe abbastanza inutile e molte persone sarebbero nei guai. Unire attende fino al termine del thread, che include l'assegnazione del valore alla variabile. – Despertar

+0

Vedi questo thread: http://stackoverflow.com/questions/6581848/memory-barrier-generators – Laurijssen

risposta

0

Dalla documentazione sembra che non sono richiesti -

MemoryBarrier è necessaria solo nei sistemi multiprocessore con debole ordinamento memoria (ad esempio, un sistema che impiega più processori Intel Itanium).

Per la maggior parte degli scopi, l'istruzione C# lock, l'istruzione SyncLock di Visual Basic o la classe Monitor forniscono modi più semplici per sincronizzare i dati.

Come si sta bloccando con join è ancora più necessario.

0

Non è necessaria la prima barriera di memoria. Devi solo chiamarli prima di accedere ai dati che sono stati modificati in un thread separato. Dato che non lo si fa all'interno di 'thread', non è necessaria la chiamata.

È possibile sbarazzarsi del secondo se si intende mantenere la chiamata di Join. Se si mantiene la seconda chiamata, è possibile sbarazzarsi di Join.

3

No, i meccanismi di sincronizzazione generano recinzioni di memoria implicite. Tutti i dati modificati da un thread saranno visibili dopo il collegamento del thread.

+1

Grazie per la risposta. Qualche documentazione per eseguire il backup di questo? – Ani

+1

@Ani: In questa fonte: http://www.albahari.com/threading/part4.aspx (che ormai tutti conoscono), menzionano quasi tutti i meccanismi di sincronizzazione come generatori di recinzione. Non menzionano esplicitamente 'Join', ma dal momento che mette il thread chiamante nello stesso stato di' Monitor.Wait', ad esempio, è un forte suggerimento che dovrebbe anche generare una fence. Inoltre, viene menzionato anche l'aspetto di un 'Task'. Sebbene unire un thread sia un po 'diverso, mi aspetto che fornisca le stesse garanzie di ordinazione della memoria. – Tudor

+0

L'ho letto, ma non ero sicuro che fosse conclusivo poiché, come dici tu, non menzionava esplicitamente "Join". – Ani