2010-06-29 21 views
10

In molti documenti MSDN, questo è scritto sotto il titolo Sicurezza del filo;msdn: Che cos'è "Thread Safety"?

"Qualsiasi membro statico pubblico (Condiviso in Visual Basic) di questo tipo è thread-safe. Non è garantito che tutti i membri dell'istanza siano thread-safe."

per esempio; here

qualcuno può spiegarlo per favore in un modo piuttosto semplice? Grazie :)

risposta

11

Eric Lippert ha un eccellente blog post su questo. Fondamentalmente è in qualche modo privo di significato da solo.

Personalmente non mi fido di MSDN troppo su questo fronte, quando vedo quella piastra della caldaia. Non significa sempre quello che dice. Ad esempio, dice la stessa cosa su Encoding - nonostante il fatto che tutti usiamo codifiche da più thread dappertutto.

A meno che non abbia motivo di credere altrimenti (cosa che faccio con Encoding) presumo di poter chiamare qualsiasi membro statico da qualsiasi thread senza alcun danneggiamento dello stato globale. Se voglio usare l'istanza dell'istanza membri dello stesso oggetto da thread diversi, presumo che vada bene se assicuro - tramite il blocco - che solo un thread utilizzerà l'oggetto alla volta. (Questo non è sempre il caso, naturalmente. Alcuni oggetti hanno filo affinità e attivamente non amano essere utilizzato da più thread, anche con bloccaggio in posizione. Controlli UI sono l'esempio evidente.)

Naturalmente, diventa difficile se gli oggetti vengono condivisi in modo noncurante - se ho due oggetti che condividono ciascuno un riferimento a un terzo, allora potrei finire a usare i primi due oggetti indipendentemente da fili diversi, con tutto il blocco appropriato - ma comunque finire per danneggiare il terzo oggetto .

Se un tipo fa sì che si pubblicizzi come thread-thread, mi auguro che possa fornire alcuni dettagli a riguardo.È facile se è immutabile: puoi semplicemente utilizzare le istanze come preferisci senza preoccuparti di loro. Sono tipi parzialmente o totalmente "thread-safe" che sono mutabili dove i dettagli sono importanti.

+3

La piccola nota di MS significa: "Non abbiamo fatto molto/nessun blocco nei metodi di istanza [probabilmente per motivi di prestazioni]. Quindi se ci vai e una dozzina di thread su di esso, e fa casino, don ' Vieni a piangere da noi, non è un bug e ti abbiamo avvertito ". – cHao

+1

@cHao: C'è molto * molto di più per ottenere diritti multi-threading rispetto al semplice blocco dei metodi di istanza. Spesso si desidera rendere funzionante atomicamente un'intera * serie * di chiamate al metodo, in questo caso nessuna quantità di blocco interno sarà di aiuto. L'iterazione attraverso una collezione è l'ovvio esempio. –

+0

@Jon: D'accordo, c'è molto di più. Ma non c'è molto di più di ciò che ci si aspetterebbe dalla MS, dato che l'atomicità integrata tra più chiamate di metodo non ha nemmeno senso da parte di chiunque apprezzi la stabilità. (Avrebbe bisogno di documenti API che dicessero cose come "Se chiami IsEmpty(), e restituisce false, DEVI chiamare Remove() o ReleaseLock() per evitare deadlock"). E anche in un singolo metodo, può causare problemi di prestazioni se è usato inutilmente. Quindi MS giustamente non si è preoccupato. Questo è il mio punto. – cHao

5

È possibile accedere a qualsiasi membro statico pubblico di quella classe da più thread contemporaneamente e non interrompere lo stato della classe. Se più thread tentano di accedere all'oggetto utilizzando i metodi di istanza (quei metodi non contrassegnati come "statici") allo stesso tempo, l'oggetto potrebbe danneggiarsi.

Una classe è "thread-safe" se tenta di accedere alla stessa istanza della classe da più thread contemporaneamente allo non causa problemi.

4

Un oggetto è "thread-safe" significa che se due thread lo utilizzano in (o molto vicino, su sistemi a singola CPU) lo stesso tempo, non c'è possibilità che sia danneggiato da tale accesso. Solitamente ciò avviene acquisendo e rilasciando blocchi, che possono causare colli di bottiglia, quindi "thread safe" può anche significare "lento" se è fatto quando non è necessario.

I membri statici pubblici sono praticamente condivisi tra i thread (Nota, VB anche chiamate "condivisa"), quindi le statistiche pubbliche sono generalmente realizzate in modo tale da poter essere utilizzate in modo sicuro.

I membri dell'istanza di solito non sono thread-safe, perché nel caso generale rallenterebbe le cose. Se si dispone di un oggetto che si desidera condividere tra i thread, pertanto, è necessario eseguire la sincronizzazione/il blocco.

0

Per comprendere ciò, considerare il seguente esempio. Nella descrizione MSDN della classe .net HashSet, c'è una parte che dice sulla sicurezza del thread. Nel caso di HashSet Class, MSDN dice "Qualsiasi membro statico pubblico (Shared in Visual Basic) di questo tipo è thread-safe. I membri di ogni istanza non sono garantiti come thread-safe. " Perchè conosciamo tutti il ​​concetto di condizioni di gara e deadlock, ma cosa vuol dire Microsoft con un semplice inglese? Se due thread aggiungono due valori ad una "istanza" di un HashSet ci sono alcune situazioni in cui possiamo ottenere il suo conteggio come uno. In questo caso, l'oggetto HashSet è corrotto poiché ora abbiamo due oggetti nell'HashSet, ma il suo conteggio ne mostra solo uno. Tuttavia, la versione statica pubblica di HashSet non affronterà mai un simile danneggiamento anche se due thread aggiungono contemporaneamente valori.