Sono tipi di dati primitivi in C # atomica (thread-safe)?
-
19-09-2019 - |
Domanda
Per esempio, ho bisogno di bloccare un valore bool
quando multithreading?
Soluzione
Non esiste una cosa come un atomica type . Solo Operazioni può essere atomica.
lettura e scrittura un tipo di dati che si inserisce in una parola (int
su un processore a 32 bit, long
su un processore a 64 bit) è tecnicamente "atomica", ma il jitter e / o processori possono decidere di riordinare istruzioni e creare così condizioni di gara inaspettate, in modo che sia necessario serializzare l'accesso con lock
, utilizzare la classe Interlocked
per la scrittura (e in alcuni casi si legge), o dichiarare il volatile
variabile.
La risposta breve è: Se due fili diversi possono accedere allo stesso campo / variabile e almeno uno di loro sarà la scrittura, è necessario utilizzare una sorta di blocco. Per i tipi primitivi che è in generale la classe Interlocked
.
Altri suggerimenti
Per la risposta definitiva andare al spec. :)
Partizione I, sezione 12.6.6 della CLI spec afferma: "Un CLI conforme deve garantire che in lettura e scrittura per allineato correttamente locazioni di memoria non più grande della dimensione della parola nativa è atomica quando tutto il accessi in scrittura a una posizione sono le stesse dimensioni. "
In modo che conferma che s_Initialized non sarà mai instabile, e che leggere e scrive a primitve tipi sono atomico.
Interlocking crea una barriera di memoria per evitare che il processore riordino legge e scrive. La serratura crea la barriera necessaria solo in questo esempio.
John.
In sostanza, voi non avete un problema "crash" da non bloccare un bool. Quello che si può avere è una condizione di competizione per l'ordine di cui il bool è aggiornato o leggere. Se si vuole che il garuntee bool viene scritto / letto da in un ordine specifico, allora che ci si vuole utilizzare una sorta di meccanismo di bloccaggio.
Un po '. C'è un ottimo thread su questo qui , ma la versione breve è che, mentre un dato lettura o scrittura può essere atomica, che è quasi mai quello che stai facendo. Ad esempio, se si vuole incrementare un numero intero, è necessario 1) leggere il valore, 2) aggiungere uno al valore e 3) memorizzare il valore indietro. Qualsiasi di queste operazioni possono essere interrotti.
Questa è la ragione per classi come "Interlocked".
statiche tipi primitivi sono threadsafe, quindi non è necessario bloccare quelle variabili tipizzate. Tuttavia, qualsiasi variabile di un tipo primitivo istanza non è garantita. Vedi qui: sono tipi primitivi come bool threadsafe
Ed ecco un altro link utile che potrebbe anche essere di interesse che trovo la soluzione molto interessante: SO Domanda: Come faccio a sapere se un metodo C # è thread-safe?