web-dev-qa-db-fra.com

Quelles sont les raisons courantes des blocages?

Les blocages sont difficiles à trouver et très inconfortables à enlever.

Comment trouver des sources d'erreur pour des blocages dans mon code? Y a-t-il des "motifs d'impasse"?

Dans mon cas particulier, il traite des bases de données, mais cette question est ouverte pour chaque blocage.

39
guerda

MISE À JOUR: Cet article de MSDN récent, outils et techniques pour identifier les problèmes de concurrence , pourrait également être d'intérêt


Stephen Toub dans l'article de MSDN moniteur d'impasse indique que les quatre conditions suivantes sont nécessaires pour que des blocages se produisent:

  • Un nombre limité d'une ressource particulière. Dans le cas d'un moniteur en C # (ce que vous utilisez lorsque vous utilisez le mot-clé de verrouillage), ce nombre limité est un, car un moniteur est un verrouillage d'exclusion mutuelle (signification qu'un seul thread peut posséder un moniteur à la fois).

  • La capacité de contenir une ressource et de demander une autre. En C #, cela s'apparente à verrouiller sur un objet, puis à verrouiller un autre avant de libérer le premier verrou, par exemple:


lock(a)
{
...
    lock(b)
    {
            ...
    }
}
  • Aucune capacité de préemption. En C #, cela signifie qu'un thread ne peut pas forcer un autre fil à libérer une serrure.

  • Une condition d'attente circulaire. Cela signifie qu'il existe un cycle de threads, chacun attendant que l'on puisse relâcher une ressource avant de pouvoir continuer.

Il poursuit pour expliquer que la façontte d'éviter les blocages est d'éviter (ou de contrecarrer) la condition quatre.

Joe Duffy discute de plusieurs techniques pour éviter et détecter des blocages, y compris un appelé nivellement de verrouillage. Dans le nivellement de verrouillage, les verrous sont attribués des valeurs numériques et les threads ne doivent acquérir que des serrures ayant des nombres plus élevés que ceux qu'ils ont déjà acquis. Cela empêche la possibilité d'un cycle. Il est également souvent difficile de bien faire bien dans une application logicielle typique aujourd'hui et une défaillance de la nivellement de verrouillage de chaque acquisition de verrouillage invite une impasse.

29
Mitch Wheat

Le scénario de blocage classique est un verrou de verrouillage de la maintien X et souhaite acquérir la serrure Y, tandis que B maintient le verrouillage Y et souhaite acquérir le verrouillage X. Étant donné que non plus compléter ce qu'ils tentent de faire ces deux finira pour toujours (à moins que les délais utilisé).

Dans ce cas, une impasse peut être évitée si A et B acquièrent les serrures dans le même ordre.

14
Brian Rasmussen

Pas de motifs d'impasse à ma connaissance (et 12 ans d'écriture d'applications de négociation multiples multithread). Mais la classe TimeDlock a été d'une grande aide pour trouver des blocages qui existent en code sans retravail massif.

http://www.randomtree.org/eric/techblog/archives/2004/10/multhreading_is_hard.html

fondamentalement, (dans DotNet/C #), vous recherchez/remplacez toutes vos relevés "verrouillage (xxx)" "" à l'aide de chronomlock.lock (xxx) "

Si une impasse est jamais détectée (verrouillage incapable d'être obtenu dans le délai d'attente spécifié, par défaut à 10 secondes), une exception est lancée. Ma version locale enregistre également immédiatement la standingTrace. Marchez la structure StackTrace (de préférence la construction de débogage avec des numéros de ligne) et vous verrez immédiatement ce que les serrures ont eu lieu au moment de l'échec et celui qui tentait d'obtenir.

Dans DotNet 1.1, dans une situation d'impasse telle que décrite, la chance aurait de la chance que tous les fils verrouillaient jetteraient l'exception en même temps. Vous obtiendriez donc plus de 2 piles et toutes les informations nécessaires pour résoudre le problème. (2.0+ peut avoir changé le modèle de threading suffisamment en interne pour ne pas être aussi chanceux, je ne suis pas sûr)

8
Peter Drier

S'assurer que toutes les transactions affectent les tables dans le même ordre correspond à la clé pour éviter les objets les plus fréquents des blocages.

Par exemple:

transaction a

UPDATE Table A SET Foo = 'Bar'
UPDATE Table B SET Bar = 'Foo'

transaction b

UPDATE Table B SET Bar = 'Foo'
UPDATE Table A SET Foo = 'Bar'

Ceci est extrêmement susceptible de résulter dans une impasse comme transaction a Obtient un verrou sur la table A, transaction b Obtient un verrou sur la table B, aucun d'entre eux ne reçoit un verrou leur deuxième commande jusqu'à la fin de l'autre.

Toutes les autres formes d'impasse sont généralement causées par une utilisation élevée de l'intensité et une impasse SQL Server, en interne, tandis que les ressources allouées.

8
Robin Day

Oui - Des blocages se produisent lorsque des processus tentent d'acquérir des ressources dans un ordre aléatoire. Si tous vos processus tentent d'acquérir les mêmes ressources dans le même ordre, les possibilités de blocage sont considérablement réduites, sinon éliminées.

Bien sûr, ce n'est pas toujours facile d'organiser ...

4
anon

Je recommande de lire cet article par Herb Sutter . Il explique les raisons des problèmes de manœuvre et met en avant un cadre dans cet article Pour aborder ce problème.

2
Alan

Le scénario d'impasse DB (selon mes observations non scientifiques) est très courant (selon mes observations non scientifiques) est très simple:

  • Deux processus lisent quelque chose (un enregistrement DB par exemple), tous deux acquièrent un verrou partagé sur la ressource associée (généralement une page de DB),
  • Tous deux essaient de faire une mise à jour, essayant de mettre à niveau leurs serrures à des exclusives - Voila, impasse.

Cela peut être évité en spécifiant la clause "pour la mise à jour" (ou similaire, en fonction de vos RDBM particuliers) si la lecture doit être suivie d'une mise à jour. De cette façon, le processus obtient le verrou exclusif du début, ce qui rend le scénario ci-dessus impossible.

1
Rafał Dowgird

Une condition qui se produit sur deux processus attendra chacune d'autres personnes avant de terminer avant précédent. Le résultat est la même procédure est suspendu. Son multitâche le plus comonciplier et la plupart des clints/serveurs.

1
karan gujjar

Le scénario typique est des plans de mise à jour incompatibles (tableaux non toujours mis à jour dans le même ordre). Cependant, il n'est pas inhabituel d'avoir des blocages lorsqu'il est sous un volume de traitement élevé.

J'ai tendance à accepter des blocages comme un fait de la vie, cela se produira un jour ou une autre, alors j'ai mon dal préparé à gérer et à réessayer une opération de sautes.

1
Otávio Décio

Pour éviter l'impasse, il y a un algorithme appelé algorithme de banquier .

Celui-ci offre également des informations utiles pour éviter l'impasse.

0
HuntM

L'impasse se produit principalement lorsqu'il existe des serrures multiples dépendantes. Dans un fil et un autre fil tente de verrouiller le mutex dans l'ordre inverse se produit. Il faut faire attention à utiliser un mutex pour éviter les blocages.

Assurez-vous de terminer l'opération après avoir relâché le verrou. Si vous avez plusieurs serrures, tels que l'ordre d'accès est ABC, la commande de libération devrait également être ABC.

0
Marcus Thornton

Dans mon dernier projet, j'ai rencontré un problème avec des blocages dans une base de données SQL Server. Le problème dans la recherche de la raison était que mon logiciel et un logiciel tiers utilisent la même base de données et travaillent sur les mêmes tables. Il était très difficile de le découvrir, ce qui provoque les impasses. J'ai fini par écrire une requête SQL pour savoir quels traitements à quelles déclarations SQL provoquent les blocages. Vous pouvez trouver cette déclaration ici: des blocages sur SQL-Server

0
Thomas Reimelt