Secondo MSDN, ReaderWriterLockSlim favorisce gli scrittori. Ciò significa che quando ci sono lettori e scrittori in coda, gli scrittori avranno la preferenza.
Questo può produrre l'inattività del lettore, il codice di prova per riprodurre questo è here. Presumo che la fame può accadere solo se la scrittura è un'operazione lunga, che coinvolge l'interruttore di contesto del thread. Almeno è sempre riprodotto sulla mia macchina, quindi per favore dimmi se ho torto.
D'altra parte, ReaderWriterLock da .net 2.0 non produce né fame né scrittore, a costo di prestazioni ridotte. Here è il codice modificato dal campione precedente, per mostrare che non sta accadendo la fame.
Quindi, tornando alla tua domanda - dipende da quali funzionalità hai bisogno dal blocco RW. Serrature ricorsive, gestione delle eccezioni, timeout - corrispondenza più vicina a qualità di produzione Blocco RW che supporta tutto quanto sopra e favorisce i lettori sarebbe probabilmente ReaderWriterLock.
Inoltre, è possibile adottare il codice dall'articolo wiki che descrive first readers-writers problem, ma ovviamente è necessario implementare manualmente tutte le funzionalità richieste dall'alto e l'implementazione presenterà un problema di scrittore.
nucleo
Lock può probabilmente simile a questa:
class AutoDispose : IDisposable
{
Action _action;
public AutoDispose(Action action)
{
_action = action;
}
public void Dispose()
{
_action();
}
}
class Lock
{
SemaphoreSlim wrt = new SemaphoreSlim(1);
int readcount=0;
public IDisposable WriteLock()
{
wrt.Wait();
return new AutoDispose(() => wrt.Release());
}
public IDisposable ReadLock()
{
if (Interlocked.Increment(ref readcount) == 1)
wrt.Wait();
return new AutoDispose(() =>
{
if (Interlocked.Decrement(ref readcount) == 0)
wrt.Release();
});
}
}
Confrontando le prestazioni di 3 implementazioni, utilizzando 3 lettore e 3 fili scrittore, utilizzando semplici in memoria operativa (con funzionamento a lungo blocco produrrebbero lettore-fame per RWLockSlim e scrittore-fame per la serratura su ordinazione):
ho fatto in modo che ciclo carico di lavoro non viene svolto dal compilatore, ma ci potrebbero essere altre insidie io non sono a conoscenza, in modo t prendi queste misure con un granello di sale. Il codice sorgente per i test è here.
L'assenza di codice non può mai essere dimostrata in modo definitivo. Ma no, è abbastanza improbabile. Si prega di evitare di fare domande per lo shopping. –
Se si desidera favorire le letture, perché non si sostituisce semplicemente l'elenco interno con un clone aggiornato? Il tuo codice sarà bloccato ma un po 'più pesante sugli aggiornamenti. – jgauffin
Sì, sembra che si possa risolvere questo problema con una copia come suggerisce jgauffin, o se la struttura dei dati è troppo grande per una copia economica, con un buffer di scrittura, quindi le scritture sono meno frequenti. Quindi si potrebbe semplicemente modificare il saldo di lettura/scrittura facendo crollare su e giù il tempo per svuotare il buffer. –