Y a-t-il un mécanisme de verrouillage en lecture / écriture qui fonctionne à travers les processus (similaires à mutex, mais lire / écrire à la place du verrouillage exclusif)? J'aimerais permettre un accès simulé en lecture, mais un accès exclusif en écriture. P>
6 Réponses :
System.threading.Mutex a un mutex qui peut être utilisé pour la communication intra-processus. Si vous souhaitez que la fonctionnalité ne supporte pas, il peut être mis en œuvre via un mutex. P>
Connaissez-vous des échantillons qui implémentent un mutex de lecture / écriture?
Ce gars dit que ce n'est en fait pas possible: Stackoverflow.com/Questtions/1008726/...
@PavelRadzivilovsky Cette question dit qu'il ne peut pas être fait sans utiliser au moins un objet de niveau du noyau, comme un mutex.
@PavelRadzivilovsky en fait, la réponse indique spécifiquement "cependant ce que vous pouvez faire est d'utiliser une serrure de spin et de revenir à un mutex chaque fois qu'il y a des conditions."
Avez-vous regardé system.threading.readerwreeLock code>? Voici le lien MSDN . P>
Ah. Mauvaise la question (toujours sur la première tasse de café). Je vais laisser cela jusqu'à quelques minutes puis la supprimer.
Windows n'inclut pas de verrouillage du lecteur de processus croisé. Une combinaison de sémaphore et de mutex pourrait être utilisée pour construire des systèmes (le mutex est dé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 - c'est-à-dire que les écrivains attendraient uniquement le mutex et les lecteurs . P>
Toutefois, si la conflit devrait être faible (c'est-à-dire qu'aucun thread contient une serrure pendant de longues), l'exclusion mutuelle peut encore être plus rapide: la complexité supplémentaire de l'écluse du lecteur-Writer submerge tout avantage de permettre aux lecteurs de plusieurs lecteurs. (A Lecteur-Writer Serrure ne sera plus rapide s'il y a beaucoup plus de lecteurs et de serrures sont conservés pour une période significative - mais seul votre profilage peut confirmer cela.) P>
non. Comme Richard noté ci-dessus, il n'y a pas de tel de la case de la boîte dans .NET. C'est comment la mettre en œuvre à l'aide d'un mutex et d'un sémaphore.
Méthode n ° 1 est décrit dans http://www.jecheng.com/blog/entries/writinganinter-processrea.html , citant: p> une alternative serait: < / p> Verrouillage lu - comme ci-dessus. Écrire le verrouillage comme suit (pseudocode): p> Il est à noter qu'une approche plus efficace est possible, comme ici: http://en.wikipedia.org/wiki/readerers-writers_problem#thiters_problem#thiters_problem-writers_problem
Recherchez les mots "Cette solution est sous-optimale" dans l'article ci-dessus. P> p>
J'ai créé cette classe en fonction de la réponse de Pavel. Je ne l'ai pas encore testé encore, mais j'ai créé une application de WinForms simple pour le tester et jusqu'à présent, cela fonctionne bien.
Veuillez noter que cela utilise un sémaphore, il ne supporte donc pas la réentruisance. p>
Merci. J'ai utilisé votre exemple comme base pour la mienne qui s'appuie uniquement sur des sémaphores et est asynchronisé / attendu amical.
Si vous voulez éviter Malheureusement, CTR code> est un entier, il ne pouvait donc fonctionner que dans les scénarios de interprocession. J'ai décidé de remplacer le comptoir entier avec un Semaphore Compteur Strong> (
ReaderCounter code>) afin qu'il puisse être utilisé pour la communication croisée. Essentiellement, j'ai utilisé
serviette (0) code> afin de diminuer strong> et
version () code> à
internal class ReaderCounter : IDisposable
{
internal ReaderCounter(string name, int maxConcurrentRead)
{
MaximumCount = maxConcurrentRead + InitialCount;
myReadCounterSemaphore = new Semaphore(InitialCount, MaximumCount, name);
myIncomingOperation = new Semaphore(1, 1, name + ".Incoming");
}
internal int Increase()
{
int counter = RetrieveCurrentCount();
// Not allowing to exceed maximum count
if (counter != MaximumCount - 1)
{
counter = myReadCounterSemaphore.Release();
}
else
{
counter++;
}
return counter;
}
internal int Decrease()
{
int counter = RetrieveCurrentCount() - 1;
myReadCounterSemaphore.WaitOne(0);
return counter;
}
public void Dispose()
{
myReadCounterSemaphore?.Dispose();
myIncomingOperation?.Dispose();
GC.SuppressFinalize(this);
}
internal int MaximumCount { get; private set; }
private const int InitialCount = 1;
private readonly Semaphore myReadCounterSemaphore;
private readonly Semaphore myIncomingOperation;
private int RetrieveCurrentCount()
{
myReadCounterSemaphore.WaitOne(0);
int counter = myReadCounterSemaphore.Release();
return counter;
}
}
Processus croisé ou fil croisé?
@Bipul - non, mais un message suggéré de rouler ma propre solution à l'aide de System.threading.Mutex, car il n'y a pas de verrouillage du lecteur de fil-fil croisé intégré au système d'exploitation.