Come sarà un blocco rispondere a una condizione di competizione?
-
05-09-2019 - |
Domanda
Per quanto tempo un filo attesa per una condizione di competizione nel seguente scenario?
Un file viene aggiunto a una raccolta:
lock(mylock)
{
// add to collection
}
E 'quindi rimosso dalla raccolta in un modo simile.
Se un thread sta cercando di aggiungere alla collezione, mentre il servizio è la rimozione dalla raccolta, chi vince?
In alternativa è che il punto di una condizione di competizione, non è possibile prevedere chi vince?
Soluzione
Se il filo rimozione tenta di bloccare un primo momento, possiede la serratura, rimuove l'elemento (se esiste), rilascia il blocco, e va avanti. Quindi il filo aggiungendo afferra la serratura e aggiunge l'elemento. Risultato finale:. esiste elemento della collezione
Se il thread aggiungendo tenta di bloccare un primo momento, possiede la serratura, aggiunge la voce, rilascia il blocco, e va avanti. Poi il filo rimozione afferra il blocco e rimuove l'elemento (appena aggiunto). Risultato finale:. l'elemento non esiste nella collezione
Né filo attenderà più a lungo di quanto sia necessario aggiungere o rimuovere un elemento dalla raccolta.
Altri suggerimenti
Come suggerisce il nome, una condizione di competizione significa che c'è una gara, e chiunque potrebbe vincere!
Utilizzando lock(obj)
come hai mostrato qui farà sì che il filo per bloccare (attesa) fino a quando i tutti gli altri thread rilasciano il loro blocco sul obj
. Questo potrebbe non accadere mai.
lock (obj)
{
// stuff
}
... è equivalente a ...
Monitor.Enter(obj);
try
{
// stuff
}
finally
{
Monitor.Exit(obj);
}
Se si desidera applicare un timeout sul blocco, utilizza questo modulo, invece:
if (!Monitor.TryEnter(obj, timeout))
{
// handle the fact that you couldn't lock
}
else
{
try
{
// stuff
}
finally
{
Monitor.Exit(obj);
}
}
Qualunque sia il filo problemi la serratura prima vincerà. Secondo thread attenderà fino a quando il primo rilascia il blocco.
C'è un altro tipo di condizione di competizione tra il 'se' e 'provare'. Ad esempio, se il filo è interrotta proprio tra allora lascia la sezione di codice bloccato. Non credo che era il punto della tua domanda, ma c'è ancora un problema in là.