Je lis je lis http://www.mono-project.com/threadsbeginnersguide . < p> Le premier exemple ressemble à ceci: p> sortie: p> wow, qu'est-ce que c'est? Malheureusement, l'explication de l'article est inadéquate pour moi. Pouvez-vous m'expliquer pourquoi les incréments sont arrivés dans un ordre jumblé? P> merci! P> p>
4 Réponses :
La synchronisation est essentielle lorsque plusieurs threads sont présents. Dans ce cas, vous voyez que les deux threads lisent et écrivent à En bref: N'utilisez jamais de sommeil pour la synchronisation :-) Mais adoptez plutôt une sorte de technique de synchronisation de fil (serrures, mutiles, sémaphores). Essayez toujours d'utiliser la serrure la plus légère possible qui remplira votre besoin ... P>
Une ressource utile est le livre de Joe Duffy, programmation simultanée sous Windows. P> this.i code>, mais aucune bonne tentative n'est effectuée pour synchroniser ces accès. Étant donné que les deux modifient simultanément la même zone de mémoire, vous observez la sortie jumblée.
L'appel au sommeil est dangereux, c'est une approche qui mène à des bugs sûrs. Vous ne pouvez pas supposer que les threads seront toujours déplacés par l'inital de 10 ms. P>
Je ne pense pas que thread.sleep () est utilisé pour essayer de synchroniser les threads. Il est juste utilisé pour que les incréments soient observables (sinon, il apparaisse tout simplement à la fois sur la console), qui a un effet secondaire de réduire les risques d'une condition de race presque nulle.
Oui, le commentaire dit que, mais il est utilisé comme une technique de synchronisation approximative, examinez le gaste de 10 ms entre les deux appels à démarrer (). En l'absence d'autres techniques, il me semble que le sommeil fait semblant une synchronisation entre les deux threads.
+1 pour le livre Joe Duffy, c'est la Bible de la concurrence Windows
Les incréments ne se produisent pas hors de l'ordre, la console.writeline (...) écrit la sortie de plusieurs threads dans une console unique à une console à une seule filetage, et la synchronisation à partir de nombreux threads à un thread est à l'origine des messages. hors de commande. p>
Je suppose que cet exemple a tenté de créer une condition de course, et dans votre cas échoué. Malheureusement, des problèmes de concurrence, tels qu'une condition de race et des blocages, sont difficiles à prédire et à se reproduire en raison de leur nature. Vous voudrez peut-être essayer de l'exécuter quelques fois de plus, modifiez-le d'utiliser plus de threads et chaque thread devrait augmenter plus de fois (disons 100 000). Ensuite, vous pourriez voir que le résultat final ne sera pas égal à la somme de tous les incréments (causés par une condition de race). P>
Désolé, console.writeine. Corrigée.
Quand j'exécute cela (sur un Dualcore), ma sortie est comme je l'aurais attendu. Vous courez deux boucles, les deux exécutant le sommeil (100). C'est très mal adapté pour démontrer une crique. p> Le code a une condition de course (comme indique le votedisclette) mais il est très peu probable de surface. P> Je ne peux pas expliquer le manque d'ordre dans votre sortie (est-ce un Vitesse réelle?), mais la classe de la console synchronisera les appels de sortie. p> Si vous laissez les appels de veille () et exécutez les boucles 1000 fois (au lieu de 10), vous pouvez voir deux coureurs à la fois progressivement de 554 à 555 ou quelque chose. P> P>
Je viens de copier ce que l'article avait, cependant, je pouvais obtenir une sortie simulée similaire en supprimant le sommeil initial dans le programme et en abaissant les couchages dans les fils à 20.
Vous avez raison, la cause est de la synchronisation de la console.
Je pense que l'écrivain de l'article a confondu des choses confuses.
voteydisciple est correct que Si une condition de raccourci a lieu appelant L'ordre des opérations 3 à 6 est sans importance, le point est que les opérations de lecture, 1 et 2 peuvent survenir lorsque la variable a une valeur x résultant de la même incrémentation de y, plutôt que chaque thread Effectuer des incrémentations pour des valeurs distinctes de x et y. p> Ceci peut entraîner la sortie suivante: - p> Quel serait encore pire est ce qui suit: - p> Cela peut entraîner la sortie suivante: - p> et ainsi de suite. p> En outre, il y a une condition de race possible entre la lecture la sortie de la console jumblée que l'auteur a décrit ne peut résulter que de l'imprévisibilité de la sortie de la console et n'a rien à voir avec une course Condition sur la variable ++ i code> n'est pas atomique et une condition de course peut se produire si la cible n'est pas verrouillée pendant l'opération mais Cela ne provoquera pas le problème décrit ci-dessus. p> ++ i code> alors les opérations internes du ++ code> code> comme: - p>
i code> et effectuer ++ i code> car la console.writeline appelle concaténatets i code> et ++ i code>. Cela peut entraîner une sortie comme: - p> i code>. Prendre un verrouillage sur i code> tandis que vous effectuez ++ i code> ou tout en concaténant i code> et ++ i code> ne changera pas cela comportement. p> p>
L'auteur de l'article mentionné indique la sortie "peut" être comme indiqué. Cela est vrai dans le sens où vous ne pouvez pas prouver que la sortie ne serait pas comme indiqué. Toutefois, dans la pratique, étant donné que cela est donné d'abord environ 10 MS Head Start, vous vous attendriez à voir une alternance de l'étape de verrouillage pour des itérations assez nombreuses avant tout «mêlée».