La pigrizia produce più condizioni di gara?

6

Recentemente ho riscontrato una condizione di competizione mentre accedevo a un'impostazione di configurazione. Dopo aver esaminato ciò che potevo del codice, sono giunto alla conclusione che la classe Configuration 'pigrizia 1 era la fonte della condizione di competizione. Il pondering che mi porta a chiedermi se la pigrizia produce naturalmente una maggiore possibilità di condizioni di gara?

Ecco come sono arrivato alla ricerca iniziale:
La classe Configuration è implementata come classe statica , che significa:

The program cannot specify exactly when the class is loaded. However, it is guaranteed to be loaded and to have its fields initialized and its static constructor called before the class is referenced for the first time in your program.

Che, se lo leggo correttamente, è un modo lungo per dire che la classe è caricata pigramente. Non ho trovato nulla che faccia riferimento all'ordinamento degli eventi quando si utilizzano risorse aggiuntive. cioè non ha detto quando il file di configurazione ( app.config ) sarebbe stato letto.

E mentre la classe stessa afferma quanto segue per la sicurezza dei thread, non è chiaro quando legge effettivamente il file di configurazione.

Any public static members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Il bit su Any instance members are not guaranteed to be thread safe è particolarmente confuso dal momento che non può essere istanziata una classe statica .

Quello che credo sia accaduto è che il mio programma ha scritto su una sezione di Configuration che è stata successivamente sovrascritta quando l'istanza statica ha completato l'inizializzazione e la lettura dal file di configurazione.

Tutto ciò mi ha portato a credere che il pigro caricamento della classe statica con la sua lettura indeterminata del file di configurazione ha creato la condizione di gara in cui mi sono imbattuto.

Il che mi porta alla mia più ampia domanda su: la pigrizia all'interno di un'applicazione offre naturalmente maggiori possibilità di condizioni di gara?

1 La particolare classe in questione è System.Configuration.Configuration dal framework .NET che è definito come public static class ConfigurationManager .

Per i dettagli sanguinosi, questa è la versione astratta del codice:

//This first line probably isn't required, but I inherited the code and didn't test removing it.
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.ConnectionStrings.ConnectionStrings[DBName].ConnectionString = passedParam;
config.Save();
...
ConnectionStringSettings connectionString = ConfigurationManager.ConnectionStrings[DBName];

Le risposte da qui suggeriscono la mia domanda, ma non riguardano direttamente la mia preoccupazione per le condizioni di gara. E questo è in qualche modo correlato ma più focalizzato su IoC.

    
posta GlenH7 05.11.2014 - 20:08
fonte

2 risposte

5

Il tuo primo link risolve il problema: la pigrizia unita agli effetti collaterali è problematica, perché l'ordine degli effetti collaterali è importante.

Per i calcoli puri, la cosa principale che cambia è l'uso dello spazio / tempo e se il calcolo produce o meno un risultato. Più specificamente, la valutazione lazy non valuterà le espressioni che non vengono utilizzate, quindi l'utilizzo del tempo può essere inferiore, ma l'utilizzo dello spazio è molto difficile da ragionare.

Per i calcoli puri che non si completano correttamente, entrambe le strategie di valutazione possono dare risultati diversi. Ad esempio, poiché la valutazione lazy non valuta le espressioni che non vengono utilizzate, se un'espressione inutilizzata avrebbe comportato un'eccezione o un ciclo infinito, il calcolo terminerà comunque.

Se il calcolo è sia puro che totale (termina sempre con successo) entrambe le strategie di valutazione danno gli stessi risultati (sebbene l'utilizzo di spazio / tempo possa essere ancora diverso).

In breve, anche se la pigrizia potrebbe richiedere di pensare in modo diverso per capire l'ordine di esecuzione, non darà luogo a condizioni di gara a meno che non sia combinato con effetti collaterali.

    
risposta data 05.11.2014 - 23:58
fonte
3

Does laziness within an application naturally yield a greater chance of race conditions?

Certo che lo è. Il codice multithreaded correttamente scritto non avrà condizioni di gara, naturalmente; le condizioni di gara sono causate dal fatto di non pensare a tutti i possibili esiti dell'ordine tra più thread. Questo è non per dire, tuttavia, che il caricamento pigro causa direttamente condizioni di gara, fornisce solo un altro potenziale punto di errore che deve essere considerato e tenuto in considerazione.

Nel tuo esempio, il tuo codice non ha fatto alcun tipo di verifyValidState nella classe Configuration , e la pigrizia ha portato a una condizione di competizione.

Per mettere tutto questo in un altro modo, uno degli assiomi su come scrivere un codice che eviti le condizioni di gara è IMMUTABILITY. Ecco un tutorial tra i molti che trattano questo argomento. Per definizione, una classe che è pigramente caricato non è immutabile: ha il valore di preinizializzazione e quindi si trasforma nel valore caricato.

Pertanto, ti suggerisco di esercitare ulteriore cautela quando utilizzo il caricamento lazy in applicazioni multithread.

    
risposta data 18.12.2014 - 00:05
fonte

Leggi altre domande sui tag