Je voudrais expliquer les blocages de threading aux débutants. J'ai vu de nombreux exemples de blocages dans le passé, certains utilisant du code et d'autres utilisant des illustrations (comme les célèbres 4 voitures ). Il existe également des problèmes classiques facilement bloqués comme The Dining Philosophers , mais ceux-ci peuvent être trop complexes pour qu'un vrai débutant les saisisse pleinement.
Je recherche l'exemple de code le plus simple pour illustrer ce que sont les blocages. L'exemple devrait:
- Se rapporte à un scénario de programmation «réel» qui a du sens
- Soyez très court, simple et direct
Que recommandez-vous?
multithreading
language-agnostic
deadlock
Roee Adler
la source
la source
Réponses:
Peut-être une simple situation bancaire.
De toute évidence, s'il y a deux threads qui tentent d'exécuter le transfert ( a, b ) et le transfert ( b, a ) en même temps, alors un blocage va se produire parce qu'ils essaient d'acquérir les ressources dans l'ordre inverse.
Ce code est également idéal pour rechercher des solutions à l'impasse. J'espère que cela t'aides!
la source
sync
peut être quelque chose comme:sync(Account & a) { a.mutex.lock(); }
.Laissez la nature expliquer l'impasse,
Deadlock: grenouille contre serpent
la source
Voici un exemple de code du département d'informatique d'une université de Taiwan montrant un exemple Java simple avec verrouillage de ressources. C'est très pertinent pour moi. Code ci-dessous:
la source
Si method1 () et method2 () seront tous deux appelés par deux ou plusieurs threads, il y a de bonnes chances de blocage car si le thread 1 acquiert le verrou sur l'objet String lors de l'exécution de method1 () et le thread 2 acquiert le verrou sur l'objet Integer lors de l'exécution de method2 () les deux attendront l'un l'autre pour libérer le verrou sur Integer et String pour continuer, ce qui ne se produira jamais.
la source
Un des exemples simples de blocage que j'ai rencontrés.
la source
private int index
fait là-bas?Voici un exemple simple en C ++ 11.
la source
Veuillez voir ma réponse à cette question . En bout de ligne, chaque fois que deux threads ont besoin d'acquérir deux ressources différentes, et le faire dans des ordres différents, vous pouvez obtenir des blocages.
la source
Un exemple auquel je peux penser est le scénario Table, lampe de poche et piles. Imaginez une lampe de poche et une paire de piles placées sur une table. Si vous vous dirigez vers cette table et attrapez les piles pendant qu'une autre personne a la lampe de poche, vous serez tous les deux obligés de vous regarder maladroitement en attendant qui remettra en premier son article sur la table. Ceci est un exemple de blocage. Vous et la personne attendez des ressources, mais aucun de vous n'abandonne sa ressource.
De même, dans un programme, un blocage se produit lorsque deux ou plusieurs threads (vous et l'autre personne) attendez que deux verrous ou plus (lampe de poche et piles) soient libérés et que les circonstances du programme sont telles que les verrous ne sont jamais libérés ( vous avez tous les deux une pièce du puzzle).
Si vous connaissez java, voici comment vous pouvez représenter ce problème:
Si vous exécutez cet exemple, vous remarquerez que parfois les choses fonctionnent correctement et correctement. Mais parfois, votre programme n'imprimera rien. C'est parce qu'une personne a les piles tandis qu'une autre personne a la lampe de poche qui les empêche d'allumer la lampe de poche provoquant une impasse.
Cet exemple est similaire à l'exemple donné par les tutoriels java: http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html
Un autre exemple est l'exemple de boucle:
Cet exemple peut soit imprimer «Non terminé» à plusieurs reprises, soit ne jamais afficher du tout «Non terminé». Le premier se produit parce que le premier thread acquiert le verrou de classe et ne le libère jamais, empêchant l'accès à 'stopLoop' par le second thread. Et le dernier se produit parce que le deuxième thread a démarré avant le premier thread, ce qui fait que la variable 'done' est vraie avant que le premier thread ne s'exécute.
la source
la source
Je considère cependant que le problème des philosophes de la salle à manger est l'un des exemples les plus simples pour montrer les blocages, car les 4 exigences de blocage peuvent être facilement illustrées par le dessin (en particulier l'attente circulaire).
Je considère que les exemples du monde réel sont beaucoup plus déroutants pour le débutant, bien que je ne puisse pas penser à un bon scénario du monde réel du haut de ma tête pour le moment (je suis relativement inexpérimenté avec la concurrence dans le monde réel).
la source
Je me suis récemment rendu compte que les combats entre couples ne sont rien d'autre qu'une impasse ... où généralement l'un des processus doit planter pour le résoudre, bien sûr, c'est la moindre priorité (Boy;)).
Voici l'analogie ...
Process1: Fille (G) Process2: Garçon (B)
Ressource1: Désolé Ressource2: Accepter sa propre erreur
Conditions nécessaires:
1. Exclusion mutuelle: Un seul de G ou B peut s'excuser ou accepter sa propre erreur à la fois.
2. Attendez et attendez: à un moment, on tient Désolé et l'autre en acceptant sa propre erreur, on attend d'accepter sa propre erreur pour se libérer désolé, et l'autre attend que désolé pour libérer l'acceptation de sa propre erreur.
3. Aucune préemption: même Dieu ne peut forcer B ou G à libérer Désolé ou à accepter sa propre erreur. Et volontairement? Vous plaisantez j'espère??
4. Attente circulaire: Encore une fois, celui qui est désolé attend que l'autre accepte ses propres erreurs, et celui qui accepte ses propres erreurs veut que l'autre s'excuse en premier. C'est donc circulaire.
Des impasses se produisent donc lorsque toutes ces conditions sont en vigueur en même temps, et c'est toujours le cas dans un combat de couple;)
Source: http://www.quora.com/Saurabh-Pandey-3/Posts/Never-ending-couple-fights-a-deadlock
la source
Un exemple de blocage plus simple avec deux ressources différentes et deux threads en attente l'un de l'autre pour libérer la ressource. Directement à partir de examples.oreilly.com/jenut/Deadlock.java
la source
If all goes as planned, deadlock will occur, and the program will never exit.
Pouvons-nous faire de cet exemple uneguarantee
impasse?Une impasse peut se produire dans une situation où a
Girl1
veut flirter avecGuy2
, qui est attrapé par un autreGirl2
etGirl2
veut flirter avec unGuy1
qui est attrapé parGirl1
. Depuis, les deux filles attendent de se vider, la condition est appelée impasse.la source
Le problème des producteurs-consommateurs ainsi que celui des philosophes de la restauration est probablement aussi simple que cela va l'être. Il a également un pseudocode qui l'illustre. Si ceux-ci sont trop complexes pour un débutant, ils feraient mieux de faire plus d'efforts pour les comprendre.
la source
Optez pour le scénario possible simpliste dans lequel une impasse peut se produire lors de la présentation du concept à vos élèves. Cela impliquerait un minimum de deux threads et un minimum de deux ressources (je pense). Le but étant de concevoir un scénario dans lequel le premier thread a un verrou sur la ressource un, et attend que le verrou sur la ressource deux soit libéré, tandis que le thread deux détient un verrou sur la ressource deux et attend le verrou sur la ressource 1 à libérer.
Peu importe quelles sont les ressources sous-jacentes; par souci de simplicité, vous pouvez simplement en faire une paire de fichiers sur lesquels les deux threads peuvent écrire.
EDIT: Ceci suppose aucune communication inter-processus autre que les verrous maintenus.
la source
J'ai trouvé qu'un peu difficile à comprendre en lisant le problème des philosophes de la restauration, l'impasse à mon humble avis est en fait liée à l'allocation des ressources. Voudrais partager un exemple plus simple où 2 infirmières doivent se battre pour 3 équipements afin d'accomplir une tâche. Bien qu'il soit écrit en java. Une méthode lock () simple est créée pour simuler la façon dont le blocage se produit, afin qu'elle puisse également s'appliquer dans un autre langage de programmation. http://www.justexample.com/wp/example-of-deadlock/
la source
Exemple simple de https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html
Production:
Dump de fil:
la source
Voici une simple impasse en Java. Nous avons besoin de deux ressources pour démontrer l'impasse. Dans l'exemple ci-dessous, une ressource est un verrou de classe (via la méthode de synchronisation) et l'autre est un entier 'i'
la source
la source
Voici une simple impasse en C #.
Si, un jour, vous appelez cela à partir du thread GUI et qu'un autre thread l'appelle également, vous risquez de vous bloquer. L'autre thread accède à EndInvoke, attend que le thread GUI exécute le délégué tout en maintenant le verrou. Le thread GUI se bloque sur le même verrou en attendant que l'autre thread le libère - ce qui ne sera pas le cas car le thread GUI ne sera jamais disponible pour exécuter le délégué que l'autre thread attend. (bien sûr, le verrou ici n'est pas strictement nécessaire - ni peut-être EndInvoke, mais dans un scénario légèrement plus complexe, un verrou peut être acquis par l'appelant pour d'autres raisons, entraînant le même blocage.)
la source
la source
la source
la source
J'ai créé un exemple de DeadLock de travail ultra simple: -
Dans l'exemple ci-dessus, 2 threads exécutent les méthodes synchronisées de deux objets différents. La méthode synchronisée A est appelée par l'objet threadDeadLockA et la méthode synchronisée B est appelée par l'objet threadDeadLockB. Dans methodA, une référence de threadDeadLockB est passée et dans methodB une référence de threadDeadLockA est passée. Maintenant, chaque thread essaie de se verrouiller sur un autre objet. Dans methodA, le thread qui maintient un verrou sur threadDeadLockA essaie d'obtenir un verrou sur l'objet threadDeadLockB et de même dans methodB, le thread qui maintient un verrou sur threadDeadLockB essaie d'obtenir un verrou sur threadDeadLockA. Ainsi, les deux threads attendront indéfiniment, créant une impasse.
la source
Laissez-moi vous expliquer plus clairement en utilisant un exemple ayant plus de 2 threads.
Supposons que vous ayez n threads contenant chacun les verrous L1, L2, ..., Ln respectivement. Disons maintenant qu'à partir du thread 1, chaque thread essaie d'acquérir le verrou de son thread voisin. Ainsi, le thread 1 est bloqué pour essayer d'acquérir L2 (comme L2 appartient au thread 2), le thread 2 est bloqué pour L3 et ainsi de suite. Le thread n est bloqué pour L1. Il s'agit maintenant d'un blocage car aucun thread ne peut s'exécuter.
Dans l'exemple ci-dessus, vous pouvez voir qu'il existe trois threads contenant
Runnable
s task1, task2 et task3. Avant l'instruction,sleep(100)
les threads acquièrent les verrous des trois objets de travail lorsqu'ils entrent dans lacall()
méthode (en raison de la présence desynchronized
). Mais dès qu'ils essaientcallAnother()
sur l'objet de leur thread voisin, ils sont bloqués, ce qui entraîne un blocage, car les verrous de ces objets ont déjà été pris.la source
la source
Un moyen sournois de se bloquer avec un seul thread est d'essayer de verrouiller le même mutex (non récursif) deux fois. Ce n'est peut-être pas le simple exemple que vous recherchiez, mais bien sûr, j'ai déjà rencontré de tels cas.
la source
Voici mon exemple détaillé de blocage , après avoir passé beaucoup de temps. J'espère que ça aide :)
la source