29 votes

Le multithreading en C# : Acquérir un verrou de lecture nécessaire ?

Est-il nécessaire d'acquérir un verrou sur une variable avant de la lire à partir de plusieurs threads ?

64voto

R. Martinho Fernandes Points 96873

La réponse courte est : cela dépend.

La réponse est longue :

  • S'il ne s'agit pas d'une valeur partagée, c'est-à-dire qu'un seul thread peut la voir (ou l'utiliser), vous n'avez pas besoin de synchronisation.

  • S'il s'agit d'une valeur immuable, c'est-à-dire que vous ne la définissez qu'une seule fois et que vous ne la lisez qu'ensuite, vous pouvez le faire sans synchronisation (tant que vous ne commencez pas à lire avant que la première écriture ne soit terminée).

  • S'il s'agit d'un type "primitif" d'au plus 32 bits (par ex. byte , short , int ), vous risquez d'obtenir des données périmées (anciennes) lors de la lecture. Si cela ne vous dérange pas, vous êtes prêt. Si les données périmées ne sont pas souhaitables, il suffit de rendre la variable volatile peut résoudre ce problème sans synchronisation supplémentaire pour les lectures. Mais si vous avez des écrivains en course, vous devrez suivre les mêmes conseils que pour long ci-dessous.

  • S'il s'agit d'un type "primitif" de plus de 32 bits (par ex. long , decimal , double ), vous avez besoin d'une synchronisation, sinon vous pourriez lire la "moitié" d'une valeur, la "moitié" d'une autre, et obtenir des résultats farfelus. Pour cela, l'approche recommandée est d'utiliser les méthodes de la classe Interlocked pour les lectures et les écritures.

  • S'il s'agit d'un type de référence, vous aurez besoin d'une synchronisation pour éviter de voir un état invalide (Jeff Lamb's exemple d'image est un bon exemple). Les lock pourrait suffire. Là encore, vous devez verrouiller les lectures et les écritures.

Il y a d'autres points à prendre en considération (la durée du verrouillage, par exemple), mais je pense que ces éléments suffisent à répondre à votre question.

7voto

Kent Boogaart Points 97432

Cela dépend du type de variable et de votre plateforme. Par exemple, la lecture des Int64 n'est pas garantie comme étant atomique sur les machines 32 bits. C'est pourquoi, Interlocked.Read .

5voto

Jeff Lamb Points 1926

Si le chargement de la valeur se fait en une seule instruction d'assemblage, il n'est pas nécessaire d'obtenir un verrou. Vous ne vous souciez pas de savoir si la valeur a changé il y a 10 minutes ou il y a 1 microseconde. Vous voulez juste la valeur maintenant.

Toutefois, si vous chargez un tableau ou une image ENORME, il serait probablement judicieux de le verrouiller. En théorie, vous pouvez être préempté pendant le chargement des données et avoir la moitié du premier élément et la moitié du deuxième élément.

S'il s'agit d'une simple variable, comme un bool ou un int, ce n'est pas nécessaire.

3voto

John Kraft Points 4559

La lecture ne nécessite pas de verrou, tant que vous ne vous souciez pas de la "justesse" de la lecture. Il n'y a de danger que si vous tentez d'écrire sans verrou.

3voto

Winston Smith Points 12029

Cela dépend s'il s'agit d'une variable locale ou partagée, et si quelque chose d'autre peut y écrire entre-temps, et ce que vous allez faire après l'avoir lue.

Si vous prenez une décision sur la base de la variable, pensez que la ligne de code suivante peut alors être basée sur des données qui sont désormais périmées.

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