Question

Y at-il un mécanisme de verrouillage en lecture / écriture qui fonctionne sur les processus (similaire à Mutex, mais en lecture / écriture à la place de verrouillage exclusif)? Je voudrais permettre un accès en lecture simultanée, mais un accès exclusif en écriture.

Était-ce utile?

La solution

Non

. Comme Richard mentionné ci-dessus, il n'y a pas de mécanisme de boîte dans .NET. Voici comment mettre en œuvre à l'aide d'un mutex et sémaphores.

Méthode n ° 1 est décrit dans http://www.joecheng.com/ blog / entrées / Writinganinter-processRea.html , citant:

// 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();
}

Une autre solution serait:

Lire verrouillage - comme ci-dessus. Écriture de verrouillage comme suit (pseudo-code):

- 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

Il faut noter que l'approche plus efficace est possible, comme ici: http: //en.wikipedia.org/wiki/Readers-writers_problem#The_second_readers-writers_problem Recherchez les mots « Cette solution est suboptimale » dans l'article ci-dessus.

Autres conseils

Windows ne comprend pas un processus de verrouillage croix Lecteur-. Une combinaison de Sémaphore et Mutex pourrait être utilisé pour les construct (le Mutex est tenu par un écrivain pour un accès exclusif ou par un lecteur qui utilise ensuite le Sémaphore pour libérer d'autres lecteurs-dire les auteurs attendraient sur tout le mutex et les lecteurs pour les deux) .

Toutefois, si affirmation devrait être faible (pas de fil conducteur est titulaire d'un verrou pour longtemps), puis l'exclusion mutuelle peut encore être plus rapide: la complexité supplémentaire du verrou de lecture-écriture submerge tout avantage de permettre aux lecteurs multiples dans (A. verrou de lecture-écriture ne sera plus rapide s'il y a beaucoup plus de lecteurs et les verrous sont maintenus pour importants temps mais seulement votre profil peut le confirmer.)

J'ai créé cette classe basée sur la réponse de Pavel. Je ne l'ai pas testé intensivement, mais je l'ai créé une application simple WinForms pour le tester et jusqu'à présent, il fonctionne bien.

S'il vous plaît noter, qu'il utilise un sémaphore, il ne supporte pas réentrée.

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 a un mutex qui peut être utilisé pour la communication intra-processus. Si vous voulez des fonctionnalités qu'il ne supporte pas, il peut être mis en œuvre au moyen d'un mutex.

Avez-vous regardé System.Threading.ReaderWriteLock? Voici le MSDN lien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top