Domanda

Legge e scrive su determinati tipi primitivi in ​​C# come bool E int sono atomici.

(Vedere la sezione 5.5, "5.5 Atomicità dei riferimenti alle variabili", nelle specifiche del linguaggio C#.)

Ma che dire dell'accesso a tali variabili tramite le proprietà?È ragionevole supporre che saranno anche atomici e thread-safe?Per esempio.È una lettura di MyProperty sotto atomico e thread-safe?:

public bool MyProperty { get { return _foo; } }

E che dire delle proprietà implementate automaticamente?

public bool MyProperty { get; }
È stato utile?

Soluzione

È necessario distinguere più da vicino tra "atomico" e "thread-safe".Come dici tu, le scritture sono atomiche per la maggior parte dei tipi di valore e dei riferimenti incorporati.

Tuttavia, ciò non significa che siano thread-safe.Significa semplicemente che se i valori "A" e "B" vengono scritti entrambi, un thread non vedrà mai qualcosa nel mezzo.(per esempio.una modifica da 1 a 4 non mostrerà mai 5, o 2, o qualsiasi valore diverso da 1 o 4.) no significa che un thread vedrà il valore "B" non appena sarà stato scritto nella variabile.Per questo, è necessario considerare il modello di memoria in termini di volatilità.Senza barriere di memoria, solitamente ottenute tramite variabili di blocco e/o volatili, le scritture nella memoria principale potrebbero essere ritardate e le letture potrebbero essere avanzate, presupponendo effettivamente che il valore non sia cambiato dall'ultima lettura.

Se avessi un contatore e gli chiedessi il suo ultimo valore ma mai ricevuto l'ultimo valore a causa della mancanza di barriere di memoria, non penso che potresti ragionevolmente chiamarlo thread-safe anche se ogni operazione potrebbe essere atomica.

Ciò non ha nulla a che fare con le proprietà, tuttavia: le proprietà sono semplicemente metodi con zucchero sintattico attorno a loro.Non forniscono garanzie aggiuntive riguardo alla filettatura.Il modello di memoria .NET 2.0 fa hanno più garanzie rispetto al modello ECMA ed è possibile che offra garanzie sull'ingresso e sull'uscita del metodo.Tali garanzie dovrebbero applicarsi anche alle proprietà, anche se sarei nervoso riguardo all'interpretazione di tali regole:a volte può essere molto difficile ragionare sui modelli di memoria.

Altri suggerimenti

Non mi è chiaro cosa stai chiedendo qui.Sembra che tu stia facendo 1 domanda su 2

  1. È la lettura di _foo mentre chiami MyProperty atomico?
  2. Il valore restituito di MyProperty è impostato atomicamente?

Per il numero 1 la risposta è sì.Come indicato dalle specifiche del linguaggio C# (e dalla CLI), è garantito che la lettura e la scrittura di variabili di determinati tipi specificati siano atomiche.Il tipo "bool" è uno di questi tipi.

Per quanto riguarda il punto 2, il posto migliore in cui cercare è la sezione 12.6.6 delle specifiche CLI.Lo afferma

Una CLI conforme deve garantire che l'accesso in lettura e scrittura a posizioni di memoria correttamente allineate non più grandi della dimensione della parola nativa (la dimensione del tipo native int) sia atomico

Considerando che per utilizzare il valore restituito di MyProperty è necessario leggere o scrivere il valore, è lecito ritenere che sia impostato in modo atomico.

Atomicità significa semplicemente che se più di un thread scrive su una variabile, il suo valore non verrà danneggiato (ad es.se occupa due byte, non otterrai mai il byte alto del thread uno e il byte basso del thread due).Lo fa non significa che la variabile è thread-safe.È ancora possibile riscontrare i soliti problemi di threading di un thread che non vede le modifiche di un altro, ecc.

Per la sicurezza del thread è necessario utilizzare il blocco (o volatile, ma su questo è più difficile ragionare).Non c'è niente di speciale nelle proprietà: anche queste devono essere rese esplicitamente thread-safe.

Se esamini il codice generato automaticamente, vedrai che le proprietà generate automaticamente sono NON thread-safe: sono semplici da ottenere/impostare su un campo generato.In effetti, farlo sarebbe un calo eccessivo delle prestazioni (specialmente quando non è necessario).

Inoltre, se stai pianificando di accedere a valori int/bool da più thread, dovresti contrassegnarlo (il campo) come volatile.Ciò impedisce sostanzialmente problemi di multithreading relativi ai registri della CPU.(Questo è dentro aggiunta al bloccaggio, non un'alternativa)

Penserei di no.Le proprietà sono essenzialmente solo metodi con un po' di zucchero sintattico per renderli un po' più facili da lavorare.Quindi, per impostazione predefinita, non sono più thread-safe di una normale chiamata al metodo (vale a dire, non sono affatto thread-safe).

Puoi inserire qualsiasi cosa in una proprietà, ad es

    Public Property foo() As Boolean
        Get
           goToLunch()
           barbecueRibs()
           return m_foo
        End Get
        Set(ByVal value As Boolean)
           takeANap()
           accessDatabase()
           messUpOtherVariables()
           m_foo = value
        End Set
    End Property
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top