Description des conditions de concurrence critique et des blocages

Traductions disponibles Traductions disponibles
Numéro d'article: 317723 - Voir les produits auxquels s'applique cet article
Agrandir tout | Réduire tout

Sommaire

Résumé

Visual Basic .NET ou Visual Basic 2005 offre la possibilité d'utiliser des threads dans les applications Visual Basic pour la première fois. Threads introduisent des problèmes de débogage, telles que les conditions de concurrence et les interblocages. Cet article explore ces deux problèmes.

Plus d'informations

Conditions de concurrence critique

Une condition de concurrence critique se produit lorsque deux threads accèdent à une variable partagée en même temps. Le premier thread lit la variable, et le deuxième thread lit la même valeur de la variable. Puis le premier thread et un deuxième thread effectuent leurs propres opérations de la valeur, et qu'ils en concurrence pour voir quel thread peut écrire dernière la valeur à la variable partagée. La valeur de la thread qui écrit sa valeur dernier est conservée, car le thread est écrit sur la valeur que le thread précédent a écrit.

Détails et exemple

Chaque thread est alloué un délai prédéfini à exécuter sur un processeur. Lors de l'expiration de la durée allouée pour le thread, le contexte du thread est enregistré jusqu'à ce que son tour suivant sur le processeur et le processeur commence l'exécution du thread suivant.

Comment une commande d'une ligne peut provoquer une condition de concurrence critique ? Examinez l'exemple suivant pour voir comment une condition de concurrence critique se produit. Il existe deux threads, et les deux sont la mise à jour d'une variable partagée appelée total (qui est représenté sous la forme dword ptr ds: [031B49DCh] dans le code de l'assembly).

Code Visual Basic :
   'Thread 1
   Total = Total + val1
				
   'Thread 2
   Total = Total - val2
				
Code de l'assembly (avec les numéros de ligne) de la compilation du code Visual Basic ci-dessus :
 'Thread 1
 1.   mov         eax,dword ptr ds:[031B49DCh] 
 2.   add         eax,edi 
 3.   jno         00000033 
 4.   xor         ecx,ecx 
 5.   call        7611097F 
 6.   mov         dword ptr ds:[031B49DCh],eax 
				
 'Thread 2
 1.   mov         eax,dword ptr ds:[031B49DCh] 
 2.   sub         eax,edi 
 3.   jno         00000033 
 4.   xor         ecx,ecx 
 5.   call        76110BE7 
 6.   mov         dword ptr ds:[031B49DCh],eax 
				
En examinant le code de l'assembly, vous pouvez voir le nombre d'opérations le processeur exécute du niveau inférieur pour exécuter une simple addition. Un thread peut être en mesure d'exécuter tout ou partie de son code d'assembly lors de son temps sur le processeur. Observez comment une condition de concurrence critique se produit à partir de ce code.

Le total est de 100, val1 est de 50 et val2 est 15. Le thread 1 Obtient une occasion de s'exécuter mais exécute uniquement les étapes 1 à 3. Cela signifie que le Thread 1 lire la variable et terminé l'ajout. Le thread 1 simplement attend maintenant d'écrire la nouvelle valeur de 150. Une fois que le Thread 1 est arrêté, Thread 2 obtient à exécuter complètement. Cela signifie qu'il a écrit la valeur qu'elle calculée (85) out au Total de la variable. Enfin, le Thread 1 reprend le contrôle et la fin de l'exécution. Il écrit la valeur (150). Par conséquent, lorsque le Thread 1 est terminé, la valeur du Total est maintenant de 150 au lieu de 85.

Vous pouvez voir comment cela peut être un problème majeur. S'il s'agissait d'un programme bancaire, le client aurait money dans leur compte ne doit pas être présent.

Cette erreur est aléatoire, car il est possible de Thread 1 terminer son exécution avant son temps sur le processeur expire et puis Thread 2 peut commencer son exécution. Si ces événements se produisent, le problème ne se produit pas. L'exécution du thread est non déterministe, donc vous ne pouvez pas contrôler l'heure ou l'ordre d'exécution. Notez également que les threads peuvent s'exécuter différemment dans le runtime et le mode débogage. En outre, vous pouvez voir que si vous exécutez chaque thread dans la série, l'erreur ne se produit pas. Ce caractère aléatoire rend ces erreurs beaucoup plus difficiles à détecter et à déboguer.

Pour éviter les conditions de concurrence critique, vous pouvez verrouiller les variables partagées, afin qu'un seul thread à la fois peut accéder à la variable partagée. Procédez avec prudence, car si une variable est verrouillée dans le Thread 1 et le Thread 2 a également besoin de la variable, l'exécution du Thread 2 s'arrête pendant que Thread 2 en attente pour le Thread 1 à la variable. (Pour plus d'informations, voir « SyncLock » dans la section « Références » de cet article).

Symptômes

Le symptôme le plus courant d'une condition de concurrence critique est des valeurs imprévisibles de variables qui sont partagées entre plusieurs threads. Cela résulte de l'imprévisibilité de l'ordre dans lequel les threads s'exécutent. Parfois un thread wins et parfois l'autre serveur wins de thread. À d'autres moments, l'exécution fonctionne correctement. Par ailleurs, si chaque thread est exécutée séparément, la valeur de la variable se comporte correctement.

Blocages

Un blocage se produit lorsque deux threads chacun verrouiller une variable différente en même temps puis essayez de verrouiller la variable de l'autre thread est déjà verrouillé. Par conséquent, chaque thread s'arrête en cours d'exécution et attend que l'autre thread libère la variable. Dans la mesure où chaque thread maintient la variable qui veut que l'autre thread, rien ne se produit, et les threads restent bloquées.

Détails et exemple

Le code suivant a deux objets, LeftVal et RightVal :
'Thread 1
SyncLock LeftVal
 SyncLock RightVal
  'Perform operations on LeftVal and RightVal that require read and write.
 End SyncLock
End SyncLock
				
'Thread 2
SyncLock RightVal
 SyncLock LeftVal
  'Perform operations on RightVal and LeftVal that require read and write.
 End SyncLock
End SyncLock
				
Un blocage se produit lorsque le Thread 1 est autorisé à verrouiller LeftVal. Le processeur s'arrête l'exécution du Thread 1 et commence l'exécution du Thread 2. Thread 2 verrous RightVal, puis tente de verrouiller les LeftVal. Car LeftVal est verrouillé, Thread 2 s'arrête et attend que LeftVal doit être publié. Étant donné que le Thread 2 est arrêté, Thread 1 est autorisé à continuer à s'exécuter. Le thread 1 essaie de verrouiller RightVal mais ne peut pas, car le Thread 2 est verrouillé. Par conséquent, Thread 1 commence à attendre jusqu'à ce que RightVal devient disponible. Chaque thread attend que l'autre thread, car chaque thread a verrouillé l'autre thread est en attente sur la variable, et aucun des deux threads sont déverrouillage la variable qu'il contient.

Un blocage ne se produit pas toujours. Si le Thread 1 exécute ces deux verrous avant que le processeur l'arrête, Thread 1 peut effectuer ses opérations et déverrouiller la variable partagée. Une fois que le Thread 1 déverrouille la variable, Thread 2 peut poursuivre son exécution, comme prévu.

Cette erreur semble évidente lorsque ces extraits de code sont placées côte à côte, mais dans la pratique, le code peut apparaître dans des modules séparés ou des zones de votre code. Présente une erreur très difficile à repérer parce que, à partir de ce même code, l'exécution correcte et exécution incorrecte peuvent se produire.

Symptômes

Un problème courant de blocage est que le programme ou le groupe de threads cesse de répondre. Il est également appelé un blocage. Au moins deux threads attendent chacun que l'autre thread verrouillé une variable. Les threads ne poursuivez pas, parce qu'aucun thread ne libère sa variable jusqu'à ce qu'il atteigne l'autre variable. L'ensemble du programme peut se bloquer si le programme est en attente sur une ou plusieurs de ces threads terminer l'exécution.

Quel est un Thread ?

Les processus sont utilisés pour séparer les différentes applications qui sont exécutent à un moment donné sur un seul ordinateur. Le système d'exploitation n'exécute pas le processus, mais faire des threads. Un thread est une unité d'exécution. Le système d'exploitation alloue du temps processeur pour un thread pour l'exécution des tâches du thread. Un processus unique peut contenir plusieurs threads d'exécution. Chaque thread gère ses propres gestionnaires d'exceptions, planification des priorités et un jeu de structures que le système d'exploitation utilise pour enregistrer le contexte du thread si le thread ne peut pas terminer son exécution pendant l'heure à laquelle il a été attribué au processeur. Le contexte est maintenu jusqu'à la prochaine fois que le thread reçoit la temps processeur. Le contexte inclut toutes les informations dont le thread a besoin pour en toute transparence continuer son exécution. Ces informations comprennent le jeu du thread des registres du processeur et de la pile des appels à l'intérieur de l'espace d'adressage du processus hôte.

Références

Pour plus d'informations, recherchez les mots clés suivants dans l'aide de Visual Studio :
  • SyncLock. Permet à un objet à verrouiller. Si un autre thread tente de verrouiller ce même objet, il est bloqué jusqu'à ce que le premier thread libère. Utiliser SyncLock avec précaution, car ils peuvent résulter d'une mauvaise utilisation de SyncLock. Par exemple, cette commande peut empêcher les conditions de concurrence critique mais provoquer des interblocages.
  • Blocage. Permet à un ensemble d'opérations thread-safe sur les variables numériques de base.
Pour plus d'informations, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la Base de connaissances Microsoft :
316422 INFO : Plan d'évolution pour les threads dans Visual Basic .NET
Pour plus d'informations, consultez le site Web MSDN suivant :
Threads et du Threading

Propriétés

Numéro d'article: 317723 - Dernière mise à jour: mardi 29 octobre 2013 - Version: 3.0
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft Visual Basic 2005
  • Microsoft Visual Basic .NET 2003 Initiation
  • Microsoft Visual Basic .NET 2002 Initiation
Mots-clés : 
kbvs2005swept kbvs2005applies kbinfo kbmt KB317723 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu d'une traduction automatique réalisée par un logiciel Microsoft et non par un traducteur professionnel. Cette traduction automatique a pu aussi être révisée par la communauté Microsoft grâce à la technologie Community Translation Framework (CTF). Pour en savoir plus sur cette technologie, veuillez consulter la page http://support.microsoft.com/gp/machine-translation-corrections/fr. Microsoft vous propose en effet des articles traduits par des professionnels, des articles issus de traductions automatiques et des articles issus de traductions automatiques révisées par la communauté Microsoft, de manière à ce que vous ayez accès à tous les articles de notre Base de connaissances dans votre langue. Il est important de noter que les articles issus de la traduction automatique, y compris ceux révisés par la communauté Microsoft, peuvent contenir des erreurs de vocabulaire, de syntaxe ou de grammaire. Microsoft ne pourra être tenu responsable des imprécisions, erreurs, ainsi que de tout dommage résultant d?une traduction incorrecte du contenu ou de son utilisation par les clients.
La version anglaise de cet article est la suivante: 317723
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com