Volatile risolverà il problema, ad es. garantirà la coerenza tra tutte le cache del sistema. Tuttavia sarà inefficienza dal momento che aggiornerà la variabile in memoria per ogni accesso R o W. Si potrebbe prendere in considerazione l'utilizzo di una barriera di memoria, solo quando è necessario, invece. Se si lavora con o gcc/ICC hanno sguardo sulla sincronizzazione built-in: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html
EDIT (per lo più su commenti PM100): Capisco che le mie convinzioni non sono un punto di riferimento così ho trovato qualcosa di citare :)
La parola chiave volatile è stata concepita per impedire ottimizzazioni del compilatore che potrebbero rendere il codice errato in presenza di determinati eventi asincroni.Ad esempio,se si dichiara una variabile primitiva come volatile, il compilatore non è consentito di memorizzare nella cache in un registro
Da Dr Dobb's
Più interessante:
campi volatili sono linearizzabile. Leggere un campo volatile è come acquistare una serratura; la memoria di lavoro viene invalidata e il valore corrente del campo volatile viene riletto dalla memoria. Scrivere un campo volatile è come liberare un blocco: il campo volatile viene immediatamente riscritto in memoria. (questo è tutto di coerenza, non si tratta di atomicità)
da L'arte della programmazione multiprocessore, Maurice Herlihy & Nir Shavit
blocco contiene codice di sincronizzazione di memoria, se non si blocca, è necessario fare qualcosa e usare parole chiave volatili è probabilmente la cosa più semplice che puoi fare (anche se è stato progettato per dispositivi esterni con memoria legata allo spazio degli indirizzi, non è il punto qui)
Cosa ti fa pensare che le scritture saranno atomiche? – bmargulies
Non sono esperto di multithreading, ma implementerei sempre il locking su qualsiasi risorsa condivisa ... –
Ho eseguito questo tipo di operazioni su un processore single-core PowerPC incorporato e funziona in modo affidabile. Meglio non fare alcun read-modify-write (come '++ sharedInt') se è possibile che due thread abbiano accesso in scrittura. (In realtà, se due thread possono scrivere, è probabilmente utile solo se limiti ** quando ** possono scrivere. Ad esempio, il thread A può cambiare 'sharedInt' da 0 a 1 mentre il thread B può cambiarlo da 1 a 0.) – Dan