Question

Je comprends la fonction principale du mot clé de verrouillage de MSDN

Instruction lock (référence C#)

Le mot-clé de verrouillage marque un bloc d'instruction comme une section critique en obtenant le verrouillage de l'exclusion mutuelle pour un objet donné, en exécutant une instruction, puis en libérant le verrou.

Quand faut-il utiliser la serrure ?

Par exemple, cela est logique avec les applications multithread car cela protège les données.Mais est-ce nécessaire lorsque l’application ne supprime aucun autre thread ?

Y a-t-il des problèmes de performances liés à l’utilisation du verrouillage ?

Je viens d'hériter d'une application qui utilise le verrouillage partout, et elle est monothread et je veux savoir si je les laisse, sont-ils même nécessaires ?

Veuillez noter qu'il s'agit plutôt d'une question de connaissances générales, la vitesse d'application est bonne, je veux savoir si c'est un bon modèle de conception à suivre à l'avenir ou si cela doit être évité à moins que cela ne soit absolument nécessaire.

Était-ce utile?

La solution

Quand faut-il utiliser la serrure ?

Un verrou doit être utilisé pour protéger les ressources partagées dans le code multithread.Pas pour autre chose.

Mais est-ce nécessaire lorsque l’application ne supprime aucun autre thread ?

Absolument pas.C'est juste une perte de temps.Assurez-vous cependant que vous n'utilisez pas implicitement des threads système.Par exemple, si vous utilisez des E/S asynchrones, vous pouvez recevoir des rappels d'un thread aléatoire, et non de votre thread d'origine.

Y a-t-il des problèmes de performances liés à l’utilisation du verrouillage ?

Oui.Ils ne sont pas très importants dans une application monothread, mais pourquoi passer des appels dont vous n'avez pas besoin ?

... si c'est un bon modèle de conception à suivre à l'avenir [?]

Tout verrouiller bon gré mal gré est un modèle de conception terrible.Si votre code est encombré de verrouillages aléatoires et que vous décidez ensuite d'utiliser un thread d'arrière-plan pour certains travaux, vous risquez de rencontrer des blocages.Le partage d'une ressource entre plusieurs threads nécessite une conception minutieuse, et plus vous pouvez isoler la partie délicate, mieux c'est.

Autres conseils

Toutes les réponses ici semblent correctes :L'utilité des verrous est d'empêcher les threads d'accéder simultanément au code verrouillé.Cependant, il existe de nombreuses subtilités dans ce domaine, l'une d'entre elles étant que les blocs de code verrouillés sont automatiquement marqués comme régions critiques par le Common Language Runtime.

L'effet du code marqué comme critique est que, si la région entière ne peut pas être entièrement exécutée, le moteur d'exécution peut considérer que l'ensemble de votre domaine d'application est potentiellement compromis et, par conséquent, le décharger de la mémoire.Citer MSDN:

Par exemple, considérons une tâche qui tente d'allouer de la mémoire tout en maintenant un verrou.Si l'allocation de mémoire échoue, l'abandon de la tâche en cours n'est pas suffisant pour garantir la stabilité de l'AppDomain, car d'autres tâches dans le domaine peuvent attendre le même verrou.Si la tâche en cours est terminée, d'autres tâches pourraient être bloquées.

Par conséquent, même si votre application est monothread, cela peut constituer un danger pour vous.Considérez qu'une méthode dans un bloc verrouillé lève une exception qui n'est finalement pas gérée dans le bloc.Même si l'exception est traitée au fur et à mesure qu'elle apparaît dans la pile d'appels, votre région critique de code ne s'est pas terminée normalement.Et qui sait comment le CLR va réagir ?

Pour plus d'informations, lisez cet article sur les périls de Thread.Abort().

Gardez à l’esprit qu’il peut y avoir des raisons pour lesquelles votre application n’est pas aussi monothread que vous le pensez.Les E/S asynchrones dans .NET peuvent très bien rappeler un thread de pool, par exemple, tout comme certaines des différentes classes de minuterie (pas le minuteur Windows Forms, cependant).

De manière générale, si votre application est à thread unique, vous n'utiliserez pas beaucoup l'instruction lock.Ne connaissant pas exactement votre application, je ne sais pas si elles sont utiles ou non – mais je suppose que non.De plus, si votre application utilise le verrouillage partout, je ne sais pas si je me sentirais de toute façon aussi confiant qu'elle fonctionne dans un environnement multithread - le développeur d'origine l'a-t-il fait en fait savent comment développer du code multithread, ou ont-ils simplement ajouté des instructions de verrouillage partout dans le vague espoir que cela ferait l'affaire ?

le verrou doit être utilisé autour du code qui modifie l'état partagé, l'état qui est modifié simultanément par d'autres threads, et ces autres bandes de roulement doivent prendre le même verrou.

Un verrou est en fait un sérialiseur d'accès à la mémoire, les threads (qui prennent le verrou) attendront que le verrou entre jusqu'à ce que le thread actuel quitte le verrou, donc l'accès à la mémoire est sérialisé.

Pour répondre à votre question, le verrouillage n'est pas nécessaire dans une application à thread unique et il a des effets secondaires sur les performances.car les verrous en C# sont basés sur des objets de synchronisation du noyau et chaque verrou que vous prenez crée une transition vers le mode noyau à partir du mode utilisateur.

Si vous êtes intéressé par les performances multithreading, un bon point de départ est Directives de thread MSDN

Toi peut Vous rencontrez des problèmes de performances avec le verrouillage des variables, mais normalement, vous construisez votre code pour minimiser le temps passé à l'intérieur d'un bloc de code « verrouillé ».

Jusqu'à retirer les serrures.Cela dépendra de ce que fait exactement le code.Même s'il s'agit d'un seul thread, si votre objet est implémenté en tant que Singleton, il est possible que plusieurs clients en utilisent une instance (en mémoire, sur un serveur) en même temps.

Oui, il y aura une certaine pénalité de performances lors de l'utilisation du verrouillage, mais elle est généralement suffisamment négligeable pour ne pas avoir d'importance.

L'utilisation de verrous (ou de toute autre instruction ou construction d'exclusion mutuelle) n'est généralement nécessaire que dans les scénarios multithread où plusieurs threads (de votre propre création ou de votre appelant) ont la possibilité d'interagir avec l'objet et de modifier l'état sous-jacent ou données conservées.Par exemple, si vous avez une collection accessible par plusieurs threads, vous ne voulez pas qu'un thread modifie le contenu de cette collection en supprimant un élément pendant qu'un autre thread essaie de le lire.

Lock(token) n'est utilisé que pour marquer un ou plusieurs blocs de code qui ne doivent pas s'exécuter simultanément dans plusieurs threads.Si votre application est monothread, elle vous protège contre une condition qui ne peut pas exister.

Et le verrouillage provoque une baisse de performances, en ajoutant des instructions pour vérifier l'accès simultané avant l'exécution du code.Il ne doit être utilisé que lorsque cela est nécessaire.

Voir le question à propos de 'Mutex' en C#.Et puis regarde ces deux questions concernant l'utilisation de l'instruction 'lock(Object)' en particulier.

Il ne sert à rien d'avoir des verrous dans l'application s'il n'y a qu'un seul thread et oui, c'est un impact sur les performances, même s'il faut un bon nombre d'appels pour que cet impact se transforme en quelque chose de significatif.

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