Questo articolo è un articolo speculare di traduzione automatica, clicca qui per saltare all'articolo originale.

Vista: 46741|Risposta: 7

[Fonte] Volatile vs. Interlock vs. lock

[Copiato link]
Pubblicato su 27/08/2018 14:40:35 | | |
Supponiamo che esista una classe che contiene un campo contatore int pubblico accessibile da più thread, e questo numero aumenterà o diminuirà soltanto.

Quando si aggiunge questo campo, quale dei seguenti schemi dovrebbe essere usato e perché?

  • lock(this.locker) this.counter++;
  • Interlocked.Increment(ref this.counter);
  • Cambia il modificatore di accesso di counter a volatile pubblico


Peggio (nessuno di essi funziona davvero)

Cambia il modificatore di accesso di counter a volatile pubblico

Questo approccio in realtà non è affatto sicuro, e il punto del volatile è che più thread che girano su più CPU buffierano i dati e riorganizzano le istruzioni eseguite.

Se è non volatile, quando la CPU A aumenta di un valore, la CPU B deve aspettare un po' per vedere il valore aumentato, il che può portare a problemi.

Se è volatile, garantisce che entrambe le CPU vedano lo stesso valore contemporaneamente. Ma non evita le operazioni di lettura e scrittura a intersecchi.

Aggiungere valore a una variabile richiede in realtà tre passaggi

1. Lettura, 2. Aggiungi 3. Scrivi

Supponiamo che il thread A legga il valore del contatore come 1 e non sia pronto ad aumentare, allora il thread B legga anch'esso il valore del contatore come 1, e entrambi i thread inizino a eseguire operazioni incrementali e di scrittura. Il valore del contatore finale è 2. Questo non è corretto, entrambi i thread hanno effettuato un'operazione di aumento, e il risultato corretto dovrebbe essere 3. Quindi etichettarlo come volatile è semplicemente insicuro.

È meglio così

lock(this.locker) this.counter++;

In questo modo è sicuro (ricordati di chiudere a chiave ovunque tu voglia accedere a questo bancone, ovviamente). Impedisce a qualsiasi altro thread di eseguire il codice bloccato. E previene anche il problema di sequenziamento delle istruzioni multi-CPU menzionato sopra. Il problema è che il lock è lento nelle prestazioni e, se usi il lock in altri punti non correlati, può bloccare gli altri thread.

Miglior

Interlocked.Increment(ref this.counter);

Questo è sicuro ed efficiente. Esegue lettura, aumento, scrittura di tre operazioni in un atomo senza essere interrotto a metà. Poiché non influisce sugli altri codici, non è necessario ricordare le serrature altrove. Ed è anche molto veloce (come dice MSDN, sulle CPU di oggi spesso è solo un'istruzione).

Ma non sono del tutto sicuro che possa anche risolvere il problema dell'ordine delle istruzioni della CPU, o se debba essere usato insieme a volatile e questo incremento.

Supplemento: Quali problemi risolve meglio la volatilità?

Dato che il volatile non può prevenire il multithreading, cosa può fare? Un buon esempio è che hai due thread, uno scrive sempre su una variabile, supponiamo che questa variabile sia queneLength, e l'altro legge sempre i dati di questa variabile. Se la lunghezza della coda non è volatile, il thread A può essere letto 5 volte, ma il thread B può vedere dati ritardati, o addirittura dati nell'ordine sbagliato. Una soluzione è usare il lock, ma in questo caso puoi anche usare volatile. Questo garantisce che il thread B veda sempre i dati più recenti scritti dal thread A, ma questa logica funziona solo se non li leggi quando lo scrivi, e se non lo scrivi quando lo leggi. Quando più thread vogliono eseguire operazioni di lettura-modifica-scrittura, devi usare Interlock o lock.





Precedente:Metodo di crittografia Java MD5
Prossimo:Linq implementa query condizionali non in e in SQL
Pubblicato su 29/08/2018 16:21:42 |
Ciao, il codice che hai fatto prima che combina highchart, istogrammi impilati e istogrammi perforabili? Vorrei chiedere se puoi inviare un codice che possa essere modificato sull'interfaccia https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light?
Pubblicato su 29/08/2018 16:22:13 |
L'intera rete è solo una tua risorsa.
Pubblicato su 29/08/2018 16:22:55 |
Perché i 90 anni passati non potevano lasciare un messaggio. Così
Pubblicato su 29/08/2018 16:40:40 |
È comodo aggiungere un indato di contatto? Consultarsi con te
 Padrone di casa| Pubblicato su 15/09/2018 13:10:16 |
private static int safeInstanceCount = 0; Operare con gli atomi
System.Threading.Interlocked.Increment(rif: safeInstanceCount); Auto-aumento 1
System.Threading.Interlocked.Decrement(rif. safeInstanceCount); Auto-meno 1
Pubblicato su 21/05/2020 16:43:54 |
Supporta il proprietario per condividere
 Padrone di casa| Pubblicato su 11/06/2020 15:00:16 |
1. Concetto

In un ambiente multithread, operazioni che non sono interrotte dai meccanismi di scheduling dei thread; Una volta iniziata questa operazione, viene eseguita fino alla fine, senza alcun cambio di contesto (passare a un altro thread) nel mezzo.

2. Classe

Classe statica System.Threading.Interlocked

3. Funzioni comunemente usate (vedi il resto)

1. statico pubblico int Diminuzione(ref int location); Reduce il valore della variabile specificata sotto forma di un'operazione atomica e memorizza il risultato

Equivalente a lock(obj){i--; }

2. static pubblico int Increment(ref int location); Incrementare il valore della variabile specificata sotto forma di un'operazione atomica e memorizzare il risultato

Equivalente a lock(obj){i++; }
Disconoscimento:
Tutto il software, i materiali di programmazione o gli articoli pubblicati dalla Code Farmer Network sono destinati esclusivamente all'apprendimento e alla ricerca; I contenuti sopra elencati non devono essere utilizzati per scopi commerciali o illegali, altrimenti gli utenti dovranno sostenere tutte le conseguenze. Le informazioni su questo sito provengono da Internet, e le controversie sul copyright non hanno nulla a che fare con questo sito. Devi eliminare completamente i contenuti sopra elencati dal tuo computer entro 24 ore dal download. Se ti piace il programma, ti preghiamo di supportare software autentico, acquistare la registrazione e ottenere servizi autentici migliori. In caso di violazione, vi preghiamo di contattarci via email.

Mail To:help@itsvse.com