73 votes

ReaderWriterLock vs lock{}

Veuillez expliquer quelles sont les principales différences et quand dois-je utiliser quoi.
L'accent est mis sur les applications web multithreadées.

73voto

Darin Dimitrov Points 528142

serrure ne permet qu'à un seul thread d'exécuter le code en même temps. Verrouillage du lecteur-écrivain peut permettre à plusieurs threads de lire en même temps ou d'avoir un accès exclusif pour l'écriture, ce qui peut être plus efficace. Si vous utilisez .NET 3.5 ReaderWriterLockSlim est encore plus rapide. Donc, si votre ressource partagée est lue plus souvent qu'elle n'est écrite, utilisez la fonction ReaderWriterLockSlim . Un bon exemple d'utilisation est un fichier que vous lisez très souvent (à chaque demande) et dont vous mettez rarement le contenu à jour. Ainsi, lorsque vous lisez le fichier, vous entrez un verrou de lecture afin que de nombreuses requêtes puissent l'ouvrir en lecture et lorsque vous décidez d'écrire, vous entrez un verrou d'écriture. L'utilisation d'un lock sur le fichier signifie essentiellement que vous ne pouvez servir qu'une seule demande à la fois.

1 votes

Donc, ce que vous dites, c'est que si le premier thread lit une valeur qui est à l'intérieur du verrou{}, aucun autre thread ne peut la lire en même temps ?

1 votes

Exactement, lock permettra à un et un seul thread d'exécuter le corps de l'instruction de verrouillage.

5 votes

"donc ça pourrait être plus efficace" : mais ça ne le sera probablement pas et votre code sera plus complexe. Elle devrait être réservée à des cas de niche.

21voto

Ian Ringrose Points 19115

Pensez à utiliser ReaderWriterLock si vous avez beaucoup de fils que seulement besoin de lire les données et ces threads sont bloqués en attendant le verrou et vous n'avez pas souvent besoin de changer les données.

Cependant, ReaderWriterLock peut bloquer un thread qui attend d'écrire pendant un long moment.

Par conséquent, n'utilisez ReaderWriterLock qu'après avoir confirmé vous obtenez haute contention pour la serrure en " la vie réelle "et vous avez confirmé que vous ne pouvez pas modifier votre conception de verrouillage pour réduire la durée de maintien du verrou .

Demandez-vous également si vous ne pouvez pas plutôt stocker les données partagées dans une base de données et la laisser s'occuper de tous les verrouillages, car cela risque beaucoup moins de vous donner du fil à retordre dans la recherche de bogues, si une base de données est suffisamment rapide pour votre application.

Sur certains cas Vous pouvez également utiliser le cache d'Aps.net pour gérer les données partagées, et simplement retirer l'élément du cache lorsque les données changent. La lecture suivante peut mettre une nouvelle copie dans le cache.

Souvenez-vous de

"Le meilleur type de verrouillage est celui dont verrouillage dont vous n'avez pas besoin (c'est-à-dire que vous ne partagez pas de données entre les threads)."

9voto

Richard Points 54016

Et le "syncblock" sous-jacent qui peut être associé à n'importe quel objet de référence - le mécanisme sous-jacent de la norme C#'s lock -support de l'exécution exclusive. Un seul thread peut avoir le verrou. C'est simple et efficace.

ReaderWriterLock (ou, dans la V3.5, le meilleur ReaderWriterLockSlim ) fournissent un modèle plus complexe. Évitez de le faire à moins que vous ne sachiez elle sera plus efficace (c'est-à-dire qu'elle disposera de mesures de performance pour la justifier).

Le meilleur type de verrouillage est celui dont vous n'avez pas besoin (c'est-à-dire que vous ne partagez pas de données entre les threads).

4 votes

+1 pour "Le meilleur type de verrouillage est celui dont vous n'avez pas besoin (c'est-à-dire ne pas partager de données entre les threads)".

7voto

ReaderWriterLock vous permet d'avoir plusieurs threads qui détiennent le ReadLock en même temps... de sorte que vos données partagées puissent être consommées par plusieurs threads à la fois. Dès qu'un WriteLock est demandé, aucun autre ReadLock n'est accordé et le code qui attend le WriteLock est bloqué jusqu'à ce que tous les threads avec ReadLock les aient libérés.

Le WriteLock ne peut être détenu que par un seul thread, ce qui permet à vos "mises à jour de données" de paraître atomiques du point de vue des parties consommatrices de votre code.

En revanche, le verrou ne permet qu'à un seul thread d'entrer à la fois, sans tenir compte des threads qui essaient simplement de consommer les données partagées.

ReaderWriterLockSlim est une nouvelle version plus performante de ReaderWriterLock avec un meilleur support pour la récursion et la possibilité de faire passer un thread d'un Lock qui est essentiellement un ReadLock au WriteLock en douceur (UpgradeableReadLock).

6voto

Hans Passant Points 475940

ReaderWriterLock/Slim est spécialement conçu pour vous aider à verrouiller efficacement dans un scénario de consommateurs multiples et de producteurs uniques. Faire cela avec l'instruction lock est possible, mais pas efficace. RWL/S prend le dessus en étant capable de spinlocker agressivement pour acquérir le verrou. Cela vous permet également d'éviter les convois de verrous, un problème avec l'instruction de verrouillage où un thread renonce à son quantum de thread lorsqu'il ne peut pas acquérir le verrou, ce qui lui fait prendre du retard car il ne sera pas reprogrammé avant un certain temps.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X