Pregunta

¿Hay un mecanismo de bloqueo de lectura / escritura que funciona en los procesos (similar al objeto mutex, pero de lectura / escritura en lugar de bloqueo exclusivo)? Me gustaría permitir el acceso simultáneo de lectura, pero el acceso de escritura exclusivo.

¿Fue útil?

Solución

No. Como Richard ha indicado anteriormente, no hay tal fuera del mecanismo de caja en .NET. Esta es la forma de ponerla en práctica usando un mutex y un semáforo.

Método # 1 se describe en http://www.joecheng.com/ blog / entradas / 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();
}

Una alternativa sería:

Leer bloqueo - que el anterior. Comentario de bloqueo de la siguiente manera (pseudocódigo):

- 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

Debe tenerse en cuenta que el enfoque más eficiente es posible, como en este caso: http: //en.wikipedia.org/wiki/Readers-writers_problem#The_second_readers-writers_problem Busque las palabras "Esta solución no es óptima" en el artículo anterior.

Otros consejos

Windows no incluye un proceso transversal de bloqueo de leer-escribir. Una combinación de semáforo y exclusión mutua se podría utilizar para los constructos (el objeto mutex está en manos de un escritor de acceso exclusivo o por un lector que luego utiliza el Semáforo para liberar otros escritores lectores-es decir, sería esperar sólo en el mutex y los lectores, ya sea para) .

Sin embargo, si se espera que la contención a ser baja (es decir, ningún hilo mantiene un bloqueo por mucho tiempo), entonces la exclusión mutua todavía puede ser más rápido: la complejidad adicional de la cerradura lector-grabador abruma cualquier beneficio de permitir que múltiples lectores en (A. bloqueo de un lector-grabador sólo será más rápido si hay muchos más lectores y bloqueos se mantienen durante tiempo significativo, pero sólo el perfilado puede confirmar esto.)

He creado esta clase basado en la respuesta de Pavel. Yo no lo he probado extensamente todavía, pero me he creado una aplicación Windows Forms simples para probarlo y hasta ahora funciona bien.

Por favor nota, que utiliza un semáforo, por lo que no admite la reentrada.

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 tiene un mutex que se puede utilizar para la comunicación intra-proceso. Si desea una funcionalidad que no es compatible, se puede implementar a través de un mutex.

¿Has mirado en System.Threading.ReaderWriteLock? Aquí está la MSDN Enlace.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top