我一直在擺弄CHESS,這似乎是一個非常有用的工具。不過,具有諷刺意味的是,我似乎在用我的一種測試方法處理海森伯。通過CHESS報道,當我運行這個測試的結果是不可預知的:什麼可能導致死鎖或以其他方式導致此併發測試不一致失敗?
- 有時候測試會通過
- 有時會導致測試失敗,沒有進一步的說明(簡單地說:「試驗失敗」)
- 有時測試將失敗,並指示覆制*
- 有時候測試會顯示「CHESS檢測僵局」
起初,我以爲這種不一致性必須是由於該測試涉及的事實使用Random
對象。一定是不同的種子價值產生了不同的結果,對吧?
所以我更新了測試,以簡單地對預定的一組種子值(0到10)上運行。線程本地Random
對象通過共享鎖Random
生成的(僞)隨機值生成種子。代碼如下
基本上
正是這樣的:
(更新:我在.NET 3.5上運行這一點,因爲CHESS只支持VS 2008我不知道這個問題可能有一些做this?)
據我瞭解,上面的代碼實際上應該是非常確定的。由於sharedRandom
與已知的種子(0和10之間)被初始化,由屬於運行Parallel.For
呼叫內的代碼的每個線程的localRandom
對象產生的值應該從一個測試運行到下一個相一致(其線程獲得該種子從sharedRandom
可能在運行之間有所不同,但在Parallel.For
內的5次迭代中,應該使用相同的5粒種子用於localRandom
)。
這就是我理解。但是從CHESS的結果來看,我傾向於相信我一定會錯過一些東西。
- 上面的代碼中是否存在死鎖,我太笨了?
- 我現在不使用併發相關的測試
Random
類? - 對於那些有使用CHESS經驗的人來說:它是一種可靠的工具嗎?有時會產生誤報嗎?這實際上是一個大問題,就好像事實證明這種情況很普遍(測試結果不一致),那麼對我而言,暫時停止使用CHESS是可取的。
* ...我還沒有弄清楚如何使用 - 但這是一個單獨的問題。
我想和你一樣(這肯定是有問題的代碼必須在註釋中),但即使當我除掉一次調用'localRandom.Next();'CHESS仍然(偶爾)報告僵局。我會更新這個問題來表明這一點。無論如何,除非今天晚些時候有人能夠解釋這種僵局是如何發生的,否則我最終可能會接受這個答案,因爲它通過澄清CHESS作爲一種工具應該如何被看待確實幫了我很大的忙。 – 2010-09-30 17:42:43
好的,我接受這個答案,因爲它是非常翔實的;但留在我心中的問題是:鑑於除了摘錄的代碼(我刪除了原始問題中的註釋代表的所有代碼)之外,我已經用絕對*沒有*的方式再現了這個問題,怎麼會有死鎖?在.NET 4.0之前(當添加'Monitor.Enter(object,ref bool)')時,使用'lock'本質上容易受到死鎖的影響嗎?也就是說,CHESS可能會嘗試放棄一個線程,只是爲了看看會發生什麼? – 2010-09-30 22:22:35
好吧,不,但我真的不知道你是如何給CHESS一個機會來檢測給定的代碼減去評論部分的問題。它在幾微秒內執行,至多。當你有* real *代碼時,它就是你鞭策的那種工具。綜合測試產生了綜合結果,該工具旨在處理現實世界的問題。當代碼需要使用usec時,它不會有時間扭曲。 – 2010-09-30 22:41:13