J'ai tripoté avec CHESS, ce qui me semble être un outil incroyablement utile. Cependant, ironiquement, j'ai l'impression d'avoir affaire à un Heisenbug dans l'une de mes méthodes d'essai. Les résultats rapportés par CHESS quand je lance ce test sont imprévisibles:Qu'est-ce qui pourrait provoquer un blocage ou provoquer l'échec de ce test de simultanéité?
- Parfois, le test passera
- Parfois, le test échouera, sans autre description (simplement: « Le test a échoué »)
- Parfois, la test échouera avec des instructions pour dupliquer *
- Parfois, le test indiquera « CHESS détecté impasse »
au départ, je pensais que cette incohérence doit être dû au fait que le test implique l'utilisation d'objets Random
. Il a dû être que différentes valeurs de semences produisaient des résultats différents, non? J'ai donc mis à jour le test pour qu'il s'exécute simplement pour un ensemble prédéfini de valeurs de départ (de 0 à 10). Les objets thread-local Random
sont ensemencés par une valeur (pseudo-) aléatoire générée par un Random
partagé dans un verrou. Le code semble essentiellement
exactement comme ceci:
(Mise à jour: Je cours ceci sur .NET 3.5, comme CHESS ne supporte que VS 2008. Je me demande si le problème pourrait avoir quelque chose à faire avec this?)
Si je comprends bien, le code ci-dessus devrait en fait être assez déterministe. Puisque sharedRandom
est initialisé avec un germe connu (entre 0 et 10), les valeurs produites par l'objet localRandom
appartenant à chaque thread exécutant le code à l'intérieur de l'appel Parallel.For
doivent être cohérentes d'un essai à l'autre (quel thread obtient quelle graine de sharedRandom
peut différer entre les exécutions, mais parmi les 5 itérations dans Parallel.For
, les mêmes 5 graines devraient être utilisées pour localRandom
).
Voilà comment le I le comprend. Mais à partir des résultats de l'ÉCHEC, j'ai tendance à croire qu'il me manque quelque chose.
- Y at-il un blocage dans le code ci-dessus que je suis trop bête pour voir?
- Est-ce que je ne devrais pas utiliser la classe
Random
dans les tests liés à la concurrence? - Pour ceux qui ont de l'expérience avec CHESS: est-ce un outil fiable? Est-ce que cela donne parfois des faux positifs? C'est en fait un gros problème, comme s'il s'avérait que ce scénario est commun (résultats de test incohérents), alors il serait peut-être bon de ne plus utiliser CHESS pour l'instant.
* ... que je n'ai pas été capable de comprendre comment utiliser - mais c'est un problème distinct.
Je pensais la même chose que vous (que sûrement le code problématique doit être dans le commentaire), mais même quand je me débarrasse de tout, sauf pour un seul appel à 'localRandom.Next();' CHESS encore (occasionnellement) des rapports une impasse. Je vais mettre à jour la question pour l'indiquer. Quoi qu'il en soit, à moins que quelqu'un arrive plus tard aujourd'hui qui puisse expliquer comment cette impasse pourrait se produire, je finirai probablement par accepter cette réponse parce qu'elle m'aide beaucoup en clarifiant comment CHESS comme outil devrait être vu. –
OK, j'accepte cette réponse, car elle est très informative; mais la question qui me reste à l'esprit est la suivante: étant donné que j'ai reproduit ce problème avec absolument rien d'autre que le code extrait (j'ai enlevé tout le code représenté par le commentaire dans la question initiale), comment peut-il y avoir une impasse? Se pourrait-il simplement que l'utilisation de 'lock' est * intrinsèquement * vulnérable aux interblocages avant .NET 4.0 (quand' Monitor.Enter (object, ref bool) 'a été ajouté)? C'est-à-dire, CHESS peut-être essayer d'avorter un fil, juste pour voir ce qui se passe? –
Eh bien, non, mais je ne vois pas vraiment comment vous donnez une chance à CHESS de détecter un problème avec le code donné, moins la section commentée. Il s'exécute en quelques microsecondes, au mieux. C'est le genre d'outil que vous utilisez lorsque vous avez du code * réel *. Les tests synthétiques engendrent des résultats synthétiques, l'outil a été conçu pour faire face aux problèmes du monde réel. Et il n'y a pas beaucoup de temps qu'il peut faire quand le code prend des usecs. –