Je comprends ce que livelocks est mais je me demandais si quelqu'un avait un bon exemple de basée sur le code de celui-ci ? Et par basée sur le code, je ne veux pas « deux personnes essayant de franchir les uns aux autres dans un couloir ». Si j’ai lu qu’encore une fois, je vais perdre mon déjeuner.
Réponses
Trop de publicités?Désinvolte commentaires de côté, un exemple qui est connu est dans le code qui tente de détecter et de gérer les situations de blocage. Si deux threads détecter un blocage, et d'essayer de "pas de côté" pour les uns les autres, sans soins, ils vont finir par être coincé dans une boucle toujours "marcher de côté et de ne jamais la gestion à aller de l'avant.
Par "pas de côté", je veux dire qu'ils allaient libérer le verrou et essayez de laisser les autres l'un de l'acquérir. Peut-on imaginer la situation avec les deux fils à faire de cette (pseudo-code):
// thread 1
getLocks12(lock1, lock2)
{
lock1.lock();
while (lock2.locked())
{
// attempt to step aside for the other thread
lock1.unlock();
wait();
lock1.lock();
}
lock2.lock();
}
// thread 2
getLocks21(lock1, lock2)
{
lock2.lock();
while (lock1.locked())
{
// attempt to step aside for the other thread
lock2.unlock();
wait();
lock2.lock();
}
lock1.lock();
}
Des conditions de course de côté, ce que nous avons ici est une situation où les deux fils, si elles entrent dans le même temps, ce sera la fin de la course à pied dans la boucle interne sans procès. Évidemment, c'est un exemple simplifié. Un naiive solution serait de mettre une sorte de hasard, dans la quantité de temps les fils d'attente.
La bonne solution est de toujours respecter le verrouillage de hiérarchie. Choisir l'ordre dans lequel vous acquérir les serrures et les tenir à cela. Par exemple, si les deux fils toujours acquérir lock1 avant lock2, alors il n'y a pas de possibilité de blocage.
Un vrai (quoique sans code exact) exemple de deux processus concurrents direct de verrouillage dans une tentative pour corriger un SQL server blocage, chaque processus à l'aide de la même attendez-algorithme de relance pour une nouvelle tentative. Alors que c'est la chance du moment, j'ai vu cela se produire sur des machines avec des caractéristiques de performance similaires en réponse à un message ajouté à un EMS sujet (par ex. l'enregistrement d'une mise à jour d'un seul graphe d'objet plus d'une fois), et ne pas être en mesure de contrôler le verrouillage de la commande.
Une bonne solution dans ce cas serait d'avoir en concurrence les consommateurs (prévention, traitement en double comme le plus haut dans la chaîne que possible en divisant le travail sur des objets indépendants).
Moins souhaitable (ok, sale-hack) la solution est de briser le moment de malchance (sorte de force de différences dans le traitement) à l'avance ou après le blocage par l'aide de différents algorithmes ou de certains élément de hasard. Cela pourrait encore avoir des problèmes à cause de sa possible le verrouillage de la prise de commande est "collante" pour chaque processus, et cela prend un minimum de temps, non comptabilisés dans l'attente de nouvelle tentative.
Encore une autre solution (au moins pour SQL Server) est d'essayer un autre niveau d'isolation (par exemple, cliché).
Un exemple ici peut-être utiliser un tryLock chronométré pour obtenir plus d’un verrou et si vous ne pouvez pas obtenir tous, marche arrière et essayez à nouveau.
Je peux imaginer qu'un tel code serait problématique que vous avez beaucoup de threads collision et d’attente pour obtenir un jeu d’écluses. Mais je ne suis pas sûr que cela est très convaincant pour moi comme un exemple simple.