"Thread safe" è un termine un po 'sfortunato perché non ha una definizione solida. Fondamentalmente significa che certe operazioni sull'oggetto sono garantite per comportarsi in modo ragionevole quando l'oggetto viene gestito tramite più thread.
Considerare l'esempio più semplice: un contatore. Supponiamo di avere due thread che stanno incrementando un contatore. Se la sequenza di eventi va:
- Thread uno legge dal contatore, ottiene zero.
- Thread di due letture dal contatore, ottiene zero.
- Il thread uno incrementa zero, scrive uno per il contatore.
- Il thread due incrementi zero, scrive uno per il contatore.
Quindi notare come il contatore ha "perso" uno degli incrementi. Le semplici operazioni di incremento sui contatori non sono thread-safe; per renderli a prova di bug puoi usare i lock, o InterlockedIncrement.
Analogamente alle code. Le code non-thread-safe possono "perdere" accodare nello stesso modo in cui i contatori non-thread-safe possono perdere incrementi. Peggio ancora, le code non sicure possono persino bloccarsi o produrre risultati pazzeschi se le si utilizza in uno scenario multi-thread in modo errato.
La difficoltà con "thread safe" è che non è chiaramente definito. Significa semplicemente "non si blocca"? Significa che verranno prodotti risultati sensibili? Ad esempio, supponiamo di disporre di una raccolta "thread-safe". Questo codice è corretto?
if (!collection.IsEmpty) Console.WriteLine(collection[0]);
No. Anche se la raccolta è "threadsafe", ciò non significa che questo codice sia corretto; un altro thread avrebbe potuto rendere la raccolta vuota dopo il controllo ma prima della linea di scrittura e quindi questo codice potrebbe bloccarsi, anche se l'oggetto è presumibilmente "thread-safe". Determinare effettivamente che ogni combinazione rilevante di operazioni è thread-safe è un problema estremamente difficile.
Ora per venire alla tua situazione attuale: chiunque ti stia dicendo "dovresti usare la classe Queue, è meglio perché è thread-safe" probabilmente non ha una chiara idea di cosa stiano parlando. Prima di tutto, Coda non è protetta da thread. In secondo luogo, se la coda è protetta da thread o non è completamente irrilevante se si sta usando l'oggetto su un singolo thread! Se si dispone di una raccolta a cui si accede su più thread, quindi, come indicato nel mio esempio sopra, si ha un problema estremamente difficile da risolvere, indipendentemente dal fatto che la raccolta stessa sia "threadsafe". È necessario determinare che ogni combinazione di operazioni eseguita sulla raccolta sia anche protetta da rischi. Questo è un problema molto difficile, e se è uno di quelli che affronti, allora dovresti usare i servizi di un esperto su questo argomento difficile.
fonte
2009-10-12 04:09:03
+1 Per la solida testimonianza di esperti. Hai anche ragione nel sottolineare che "thread safe" è un concetto piuttosto sfocato. –
Mi piace come ogni domanda relativa alla sicurezza del thread abbia una risposta dallo stesso tipo, di cui ho letto la lettura per circa 2 ore. –