Domanda

Esiste un meccanismo di bloccaggio di lettura / scrittura che funziona su processi (simili a Mutex, ma in lettura / scrittura al posto di blocco esclusivo)? Vorrei per consentire l'accesso simultaneo in lettura, ma l'accesso in scrittura esclusivo.

È stato utile?

Soluzione

No. Come osservato in precedenza Richard, non esiste fuori dalla scatola meccanismo NET. Questo è come implementare utilizzando un mutex e un semaforo.

Metodo # 1 è descritta in http://www.joecheng.com/ blog / voci / Writinganinter-processRea.html , citando:

// create or open global mutex
GlobalMutex mutex = new GlobalMutex("IdOfProtectedResource.Mutex");
// create or open global semaphore
int MoreThanMaxNumberOfReadersEver = 100;

GlobalSemaphore semaphore = new GlobalSemaphore("IdOfProtectedResource.Semaphore", MoreThanMaxNumberOfReadersEver);

public void AcquireReadLock()
{
  mutex.Acquire();
  semaphore.Acquire();
  mutex.Release();
}

public void ReleaseReadLock()
{
  semaphore.Release();
}

public void AcquireWriteLock()
{
  mutex.Acquire();
  for (int i = 0; i < MoreThanMaxNumberOfReadersEver; i++)
    semaphore.Acquire(); // drain out all readers-in-progress
  mutex.Release();
}

public void ReleaseWriteLock()
{
  for (int i = 0; i < MoreThanMaxNumberOfReadersEver; i++)
    semaphore.Release();
}

Un'alternativa potrebbe essere:

Leggi bloccaggio - come sopra. Scrivi bloccaggio come segue (pseudocodice):

- Lock mutex
- Busy loop until the samaphore is not taken AT ALL:
-- wait, release.
-- Release returns value; 
-- if value N-1 then break loop.
-- yield (give up CPU cycle) by using Sleep(1) or alternative
- Do write
- Release mutex

Si deve notare che l'approccio più efficiente è possibile, come in questo caso: http: //en.wikipedia.org/wiki/Readers-writers_problem#The_second_readers-writers_problem Cercare le parole "Questa soluzione è ottimale" nel suddetto articolo.

Altri suggerimenti

di Windows non include un processo trasversale di blocco Reader-Writer. Una combinazione di semaforo e Mutex potrebbe essere usato per quelli Construct (il mutex è tenuto da uno scrittore per l'accesso esclusivo o da un lettore, che utilizza quindi il semaforo di rilasciare altri scrittori lettori-vale a dire avrebbe aspettato su appena il mutex e lettori per entrambi) .

Tuttavia, se contesa dovrebbe essere basso (vale a dire senza filo contiene un blocco per lungo tempo), allora la mutua esclusione può essere ancora più veloce: l'ulteriore complessità della serratura di lettura-scrittura travolge qualsiasi vantaggio di consentire più lettori in (A. blocco di lettura-scrittura sarà solo più velocemente se ci sono molti lettori più e si blocca si svolgono per gran parte del tempo, ma solo il vostro profiling possono confermare questo.)

Ho creato questa classe in base alla risposta di Pavel. Non ho ancora testato estensivamente, ma ho creato una semplice applicazione WinForms per provarlo e finora funziona bene.

Si prega di notare, che usa un semaforo, in modo che non supporta rientranza.

public class CrossProcessReaderWriterLock
{
    private readonly string _name;
    const int _maxReaders = 10;

    readonly Mutex     _mutex;
    readonly Semaphore _semaphore;

    public CrossProcessReaderWriterLock(string name)
    {
        _name = name;
        _mutex     = new Mutex(false, name + ".Mutex");
        _semaphore = new Semaphore(_maxReaders, _maxReaders, name + ".Semaphore");
    }

    public void AcquireReaderLock()
    {
        //Log.Info($"{_name} acquiring reader lock...");

        _mutex    .WaitOne();
        _semaphore.WaitOne();
        _mutex    .ReleaseMutex();

        //Log.Info($"{_name} reader lock acquired.");
    }

    public void ReleaseReaderLock()
    {
        _semaphore.Release();

        //Log.Info($"{_name} reader lock released.");
    }

    public void AcquireWriterLock()
    {
        //Log.Info($"{_name} acquiring writer lock...");

        _mutex.WaitOne();

        for (int i = 0; i < _maxReaders; i++)
            _semaphore.WaitOne(); // drain out all readers-in-progress

        _mutex.ReleaseMutex();

        //Log.Info($"{_name} writer lock acquired.");
    }

    public void ReleaseWriterLock()
    {
        for (int i = 0; i < _maxReaders; i++)
            _semaphore.Release();

        //Log.Info($"{_name} writer lock released.");
    }
}

System.Threading.Mutex ha un mutex che può essere utilizzato per la comunicazione intra-processo. Se volete funzionalità che non supporta, può essere implementato tramite un mutex.

Hai guardato System.Threading.ReaderWriteLock? Ecco il MSDN Link.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top