2012-01-08 15 views
21

Mi chiedo se questo è completamente sicuro per i thread e se la parola chiave volatile debba essere presente o meno.È questo (booster volatile) sempre thread safe?

using System.Threading; 

class Program 
{ 
    private static volatile bool _restart = true; 

    private static void Main() 
    { 
     while (_restart) 
     { 
      // Do stuff here every time for as long as _restart is true 
      Thread.Sleep(1); 
     } 
    } 

    private static void SomeOtherThread() 
    { 
     Thread.Sleep(1000); 
     _restart = false; 
    } 
} 

penso che sia, ma voglio ricontrollare, dal momento che io non sono sicuro al 100% voglio solo essere sicuro.

Penso che la parola chiave volatile sia richiesta perché non sarebbe mai possibile avere il valore memorizzato nella cache nei registri o in uguali ottimizzazioni.

+0

Non è proprio quello che significa thread-safe. Thread-safe (in genere) significa che più chiamate alla stessa classe/libreria non spazzeranno via i dati statici memorizzati dalla libreria. –

+0

Nel tuo esempio, se tutto quello che vuoi è contrassegnare un altro thread, non vedo cosa non funzionerà. –

+0

@JonathonReinhart Sì, l'ho solo come bandiera. Se questo non è thread-safety è la concorrenza? – Aidiakapi

risposta

11

Cosa risposto SLaks è corretto, naturalmente, ma per rispondere alla tua domanda: sì, su entrambi i fronti: è sicuro, deve essere dichiarata volatile.

+0

Grazie, è quello che volevo sapere :) – Aidiakapi

10

È necessario sostituire l'intero costrutto con uno ManualResetEvent, che è sia thread-safe che più veloce.

private static readonly ManualResetEvent ev = new ManualResetEvent(); 

private static void Main() 
{ 
    ev.WaitOne() 
} 

private static void SomeOtherThread() 
{ 
    Thread.Sleep(1000); 
    ev.Set(); 
} 
+2

Questo è * non * quello che voglio, non voglio che il thread principale (in questo caso) per dormire. Voglio solo che continui a scorrere. Altrimenti userei anche un altro costrutto. Scusa se non sono stato chiaro su questo, per favore vedi l'aggiornamento. – Aidiakapi

+0

+1 è meglio .., comunque @Aidiakapi nota che la tua soluzione funzionerà correttamente; la parola chiave 'volatile' svuota il nuovo valore '_restart = false' nella memoria principale e quindi il valore aggiornato sarà visto nel metodo' Main'. –