2009-07-23 16 views
7
class StopIt 
{ 
    private bool stop; 

    void Loop() 
    { 
    while (!stop) 
    { 
     // work 
    } 
    } 

    void Stop() 
    { 
    stop = true; 
    } 
} 

In pratica, se il metodo Loop è in esecuzione in un thread e Stop viene chiamato da un altro, l'operazione si interrompe correttamente? Capisco che bool leggere/scrivere sia atomico. Ma è abbastanza? Se il ciclo del filo non viene fermato immediatamente, c'è un problema. Dovrei contrassegnare l'arresto volatile?È un'operazione atomica sufficiente

+0

La mia regola: se non si conosce ESATTAMENTE cosa significa volatile, non si dovrebbe tentare di scrivere programmi senza blocco. Dal momento che stai facendo la domanda, non sai cosa significa. Quindi non tentare di scrivere un programma lock-free. Stai attento. Usa un lucchetto. Le serrature sono costose solo se contese; non provare a renderlo bloccato fino a quando non sei sicuro che (1) hai un problema di prestazioni (2) il blocco è la causa del problema e (3) capisci cosa significa volatile fino al livello dell'hardware del processore. –

+0

Non dovrei usare il blocco quando si accede allo stop? Se è così, allora come posso bloccare l'accesso in lettura nel ciclo while? –

+1

@yummy: è difficile bloccare la lettura come sembra ora, dal momento che accedi al campo direttamente nel tuo ciclo while. Se incapsuli quello letto in una proprietà (o in un metodo), puoi usare un lucchetto per leggere il valore. –

risposta

10

Sì, si dovrebbe assolutamente contrassegnare stop come volatile.

L'atomicità non è sufficiente, non garantisce che un thread "vedrà" mai le modifiche apportate da un altro.

Mentre la mia comprensione della volatile è attualmente in fase alcuni interventi di chirurgia, è possibile all'incirca pensare a una scrittura ad una variabile volatile, come "fare in modo che altri possano vedere questo immediatamente!" e una lettura da una variabile volatile come "Voglio vedere l'ultimo valore!"

Senza rendere stop volatile, il ciclo potrebbe continuare all'infinito, anche se Stop() viene chiamato in un thread diverso. Fondamentalmente il JIT ha potuto leggere abbastanza ragionevolmente la variabile in un registro e quindi solo leggere dal registro per sempre.

Infatti, se "lavoro" sempre coinvolge chiamare un metodo non-inline, credo che il JIT è attualmente costretto a fare un volatili leggere in ogni caso, ma che è solo una corrente di limitazione pratica ... la teoria si dice dovrebbe renderlo volatile.

+0

Come può un thread accedere a ciò che accade in un altro? – KdgDev

+0

È vero anche il contrario: volatile non è sufficiente per l'atomicità! – Noldorin

+0

@Noldorin: non rilevante in questo caso, poiché la scrittura sul valore booleano * sarà atomica in base alla sezione 12.6.6 della partizione 1 di ECMA 335. –

Problemi correlati